2013-02-28 29 views
11

Tôi đã sử dụng #ifdef Win32 cho các cuộc gọi an toàn như nhau sprintf_s nhưng bây giờ tôi muốn xây dựng dự án với MinGW và bây giờ nó chỉ là sai. Tôi cần sử dụng #ifdef VC++ hoặc bằng cách nào đó như thế. Có thể không?Cách #ifdef bằng CompilerType? GCC hoặc VC++

+2

Ngoài ra, bạn chỉ có thể sử dụng 'snprintf()' là một hàm chuẩn thực hiện cùng một điều. – FatalError

+0

@ FatalError Không có trong Visual C++, nó không; Than ôi chỉ có hỗ trợ C89 và 'snprintf' không được bảo đảm tồn tại trong C89. Có '_snprintf' tương tự, mặc dù IIRC không được đổi tên thành' snprintf' bởi vì điều đó có sự khác biệt một cách tinh tế. – Sebivor

Trả lời

31
#ifdef __GNUC__ 
/*code for GNU C compiler */ 
#elif _MSC_VER 
/*usually has the version number in _MSC_VER*/ 
/*code specific to MSVC compiler*/ 
#elif __BORLANDC__ 
/*code specific to borland compilers*/ 
#elif __MINGW32__ 
/*code specific to mingw compilers*/ 
#endif 
+1

'__GNUC__' là một phương ngữ ngôn ngữ, không phải là một trình biên dịch. Hầu hết các trình biên dịch (bao gồm Clang và ICC) sẽ xác định '__GNUC__' ít nhất là đôi khi. – Quuxplusone

+0

@Quuxplusone '__GNUC__' là một phương ngữ ngôn ngữ, nhưng mã bạn viết thường dành cho trình biên dịch và hy vọng con người. Tuy nhiên, nếu bạn có nghĩa là tôi phải cải thiện câu trả lời này bằng cách thay đổi '/ * mã cho trình biên dịch GNU C * /' thành '/ * trong GNU C Dialect * /', bạn có thể gửi đề xuất để cải thiện –

+0

Chỉ cần chỉ ra rằng nếu OP đang cố gắng phân biệt GCC với VC++ từ "một số trình biên dịch khác cũng hỗ trợ GNU C" (ví dụ ICC, Clang, Green Hills, ...) thì việc kiểm tra '__GNUC__' sẽ không đủ. Trong trường hợp đó, [câu hỏi/câu trả lời này sẽ phù hợp với tình huống của họ tốt hơn] (https://stackoverflow.com/a/28166605/1424877). – Quuxplusone

8

Tốt hơn là bạn nên sử dụng ký hiệu di động. Tôi hiểu đôi khi những biểu tượng đó có thể không được xác định, vì vậy bạn có thể xem Predef project để biết danh sách các macro tiền xử lý mở rộng về tiêu chuẩn, trình biên dịch, thư viện, hệ điều hành và kiến ​​trúc mà không phải là di động.

Tuy nhiên, chức năng bạn đề cập cụ thể trong câu hỏi này đã được đưa vào tiêu chuẩn C11 như một phần của Annex K.3, the bounds-checking interfaces (library).

K.3.1.1p2 trạng thái:

Các chức năng, macro và các loại công bố hoặc quy định tại K.3 và subclauses của nó được khai báo và xác định bởi tiêu đề của mình nếu __STDC_WANT_LIB_EXT1__ được định nghĩa là một macro mà mở rộng đến số nguyên hằng số 1 tại điểm trong tệp nguồn nơi tiêu đề thích hợp được bao gồm lần đầu tiên

Vì vậy, bạn nên đặt tùy chọn khi kiểm tra __STDC_WANT_LIB_EXT1__ và chỉ sử dụng biểu tượng trình biên dịch cụ thể khi không tồn tại.

+1

Rất đẹp. Chưa bao giờ nghe nói về liên kết đó trước đây, cảm ơn vì đã đăng nó. –