Từ header string.h
:
/* Reentrant version of `strerror'.
There are 2 flavors of `strerror_r', GNU which returns the string
and may or may not use the supplied temporary buffer and POSIX one
which fills the string into the buffer.
To use the POSIX version, -D_XOPEN_SOURCE=600 or -D_POSIX_C_SOURCE=200112L
without -D_GNU_SOURCE is needed, otherwise the GNU version is
preferred. */
Lưu ý, hãy cẩn thận khi sử dụng phần mở rộng GNU, bật chúng lên (_GNU_SOURCE
) cuối cùng, trước khi bao gồm các tiêu đề mà bạn muốn nó ảnh hưởng (hoặc undefine nó một cách chiến lược). Không cần phải lo lắng nếu không sử dụng phần mở rộng GNU, mặc dù.
Nói chung, nếu GNU lệch khỏi POSIX trong hành vi mặc định, bạn sẽ thấy một số nhận xét trong tiêu đề để cho biết cách bạn có thể nhận được hành vi POSIX. Nó cũng (thường) được ghi lại trong sách hướng dẫn glibc, nhưng điều đó không phải lúc nào cũng làm cho nó trở thành những trang người đàn ông bị cô đặc.
Sửa
Hãy thử kiểm tra này đơn giản:
#include <string.h>
#ifdef _GNU_SOURCE
#error "Something turned it on!"
#endif
Hoặc trực tiếp hơn
#ifdef _GNU_SOURCE
#undef _GNU_SOURCE
#endif
#include <string.h>
Nếu _POSIX_C_SOURCE={version}
được định nghĩa, bạn nên có phiên bản POSIX trừ khi cái gì khác gây ra phiên bản GNU được ưa chuộng.
Điều duy nhất tôi có thể nghĩ về điều đó sẽ là _GNU_SOURCE
. Tôi chắc chắn điều này không có trên cờ dòng lệnh của bạn, bạn sẽ thấy nó. Nó có thể là một thư viện được bao gồm đã bật nó lên.
Đó là ý của tôi về các tiện ích mở rộng là 'phức tạp' khi yêu cầu triển khai POSIX được ưu tiên, ngay cả khi bạn không phải là người bật chúng.
Sửa
Nếu cái gì đó đang bật _GNU_SOURCE
(Tôi không thể nhớ nếu tăng làm hay không, tôi không sử dụng C++ gần như là nhiều như tôi làm C), có thể bạn muốn cho phép nó làm như vậy. Bạn có thể sử dụng --undef "[macro]" -U[macro]
từ dòng lệnh.Tuy nhiên, đó sẽ không hoạt động nếu mã thư viện trông như thế này:
#ifndef _GNU_SOURCE
#define _GNU_SOURCE
#endif
#include <stdio.h>
#include <string.h>
#ifdef _GNU_SOURCE
#error "It didn't work"
#endif
int main(void)
{
return 0;
}
Vấn đề là, vào thời điểm mã của bạn thực sự bao gồm string.h
, cái gì khác đã bật mở rộng và bao gồm nó. Bao gồm bảo vệ tự nhiên ngăn bạn bao gồm nó hai lần.
Hãy thử tắt một cách rõ ràng _GNU_SOURCE
và bao gồm string.h
trước mọi thứ khác. Điều này ngăn không cho các thư viện khác bật các tiện ích này. Tuy nhiên, những thư viện đó có thể không hoạt động nếu không có chúng. Một số mã chỉ hoạt động GNU 'mong đợi', và không bao gồm dự phòng cho POSIX.
Tôi đã gặp phải sự thất vọng tương tự với mã thư viện không hoạt động mà không có asprintf()
.
Bạn có chắc chắn không có tệp tiêu đề nào hay 3 tiêu đề bên nào xác định ví dụ: '_GNU_SOURCE'? – nos