2016-10-04 20 views
6

Chúng tôi đang gặp lỗi trình biên dịch khi sử dụng sigemptyset trên Cygwin trong Newlib. Lỗi xảy ra với trình biên dịch C++, nhưng chỉ khi sử dụng -std=XXX. Không có tùy chọn chuẩn, chương trình thử nghiệm sẽ biên dịch và thực thi như mong đợi.Lỗi "sigemptyset không được khai báo trong phạm vi này" khi sử dụng C + 11 và Newlib

Chương trình thử nghiệm bên dưới và tiêu đề yêu thích của Cygwin theo sau. Tôi không thấy bất cứ điều gì đáng ngờ trong tiêu đề Cygwin.

Tôi đã thử các thủ thuật như #define _GNU_SOURCE#define _XOPEN_SOURCE 700. Tôi cũng đã thử các thủ thuật như sử dụng các không gian tên toàn cầu và std. Liên quan, xem What does -D_XOPEN_SOURCE do/mean?Namespace issues in c++11?.

Điều gì gây ra lỗi biên dịch và cách khắc phục sự cố?


$ cat ~/test.cxx 
#include <signal.h> 

int main(int argc, char* argv[]) 
{ 
    struct sigaction new_handler; 
    return sigemptyset(&new_handler.sa_mask); 
} 

Nếu không có một -std=XXX, nó kết quả trong:

$ g++ -c test.cxx 
$ 

Với -std=XXX, nó kết quả trong:

$ g++ -std=c++03 -c test.cxx 
test.cxx: In function int main(int, char**): 
test.cxx:6:44: error: sigemptyset was not declared in this scope 
    return sigemptyset(&new_handler.sa_mask); 

Và khi cố gắng sử dụng sigemptyset trong không gian tên toàn cầu :

$ g++ -std=c++03 -c test.cxx 
test.cxx: In function ‘int main(int, char**)’: 
test.cxx:6:12: error: ‘::sigemptyset’ has not been declared 
    return ::sigemptyset(&new_handler.sa_mask); 
      ^

Things get worse when using -std=gnu++03 and friends.

+0

* đoán * của tôi? Khi bạn sử dụng tiêu chuẩn C++ đơn giản không có phần mở rộng GNU, bạn cần xác định '_XOPEN_SOURCE' trước khi bao gồm' '. –

+0

Ngoài ra, bạn nên tìm trong '' cho tệp tiêu đề tín hiệu Cygwin. –

+0

Cảm ơn @Joachim. Khi grepping cho 'sigemptyset' có hai lần truy cập: (1)'/usr/include/bash/sig.h' và (2) '/ usr/include/sys/signal.h'. – jww

Trả lời

1

Vấn đề này đã làm việc thông qua tại Botan 2.1.0 does not compile under Cygwin 2.8.0 with g++ 5.4.0. Dưới đây là hai ý kiến ​​quan tâm.

Thứ nhất, từ noloader:

Cygwin sử dụng Newlib, không GNU của libstdc++. Khi không có -std=c++XX, GCC hiện tại mặc định là -std=gnu++11 (GCC 6 changes to gnu++14 theo mặc định). Tôi tin rằng các nguồn GNU đảm bảo các chức năng dự kiến, như sigaction, là khả dụng.

Bạn có thể xem xét thử -D_XOPEN_SOURCE=600 hoặc -D_XOPEN_SOURCE=700.

Đồng thời xem C++ and feature guards Warning Question trên danh sách gửi thư Newlib.

Thứ hai, từ SideChannel:

Nhờ @noloader. Cho đến bây giờ -std=c++11 được đặt trong Makefile. thông tin quan trọng là trong chuỗi đề cập ở trên trên danh sách gửi thư của Newlib . Yaakov Selkowitz đã viết:

G ++ định nghĩa _GNU_SOURCE vào các mục tiêu glibc, có nghĩa là -std=c++NN là, trái với các tài liệu, không nghiêm ngặt theo tiêu chuẩn ISO C++:

Vì vậy, việc áp dụng patch #987 VÀ thiết -std=gnu++11 công trình đối với tôi . Tôi không thử các tùy chọn -D khác (tôi nghĩ thực tế khác là nhiều hơn cơ bản). Tóm tắt, @randombit vui lòng áp dụng PR # 987 và đặt -std=gnu++11 cho gcc trong Cygwin.

2

Chức năng là phần mở rộng theo tiêu chuẩn ISO C.
http://pubs.opengroup.org/onlinepubs/9699919799/functions/sigemptyset.html

như vậy được bảo vệ trên /usr/include/sys/signal.h bởi
__XSI_VISIBLE> = 4

thấy /usr/include/sys/features.h để biết chi tiết.

Như mặc định các thiết lập định nghĩa lớn nhất được sử dụng, nhưng -std=XXX làm giảm phạm vi định nghĩa

+0

Cảm ơn Matzeri. Cách thú vị của nó là vấn đề bề mặt. Dường như mọi thứ sẽ thất bại, hoặc mọi thứ sẽ thành công. Ở mức tối thiểu, có vẻ như '-std = gnu ++ XX' nên đã biên dịch cùng với không có' -std' vì không phải là ISO C. Nếu tôi nhớ chính xác, một số '-std = gnu ++ XX' là một mặc định khi sử dụng trình biên dịch C++ của GCC. Tôi đoán cách của nó newlib làm những việc kể từ khi nó không có trong libstdC++. – jww

+0

tiêu đề newlib đang được phát ngẫu nhiên. Có những thay đổi đáng chú ý trong những tháng cuối cùng và '/ usr/include/sys/features.h' cung cấp các hướng dẫn hiện hành. – matzeri

Các vấn đề liên quan