2016-05-31 16 views
12

Gần đây tôi đã vấp phải một điều gì đó lạ: chuyển đổi boolean thành con trỏ hoạt động trong Visual Studio 2013 và 2015 nhưng không phải trên GCC cũng như Clang (đã thử trong 3.5).Chuyển đổi một bool (false) thành con trỏ hợp pháp trong C++?

#include <iostream> 

using namespace std; 

void foo(int *ptr) 
{ 
    std::cout << "foo"; 
} 

int main() 
{ 
    foo(false); 
} 

Lỗi trong GCC:

main.cpp: In function 'int main()': 
    main.cpp:13:13: error: cannot convert 'bool' to 'int*' for argument '1' to 'void foo(int*)' 
    foo(false); 
      ^

tôi đoán là sai được chuyển thành 0 tương đương với NULL. Thay thế cuộc gọi thành foo với foo(true) làm cho quá trình biên dịch thất bại với mọi trình biên dịch.

Vì vậy, câu hỏi của tôi là: mã này có được biên dịch không? Tôi không thấy lợi ích của việc chuyển đổi giả thành con trỏ, có vẻ như tôi sẽ chỉ là nguyên nhân của lỗi sau khi lạm dụng/tái cấu trúc v.v.

+3

liên quan: [Ngăn cast im lặng từ false thành con trỏ] (http://stackoverflow.com/q/21025179/3425536) – emlai

+1

@ DieterLücking Tôi không nghĩ rằng đó là trùng lặp, OP muốn biết là nó cho phép và mà trình biên dịch (gcc, clang, vc) là chính xác. – songyuanyao

+0

Chết tiệt, tôi đã tìm kiếm và không tìm thấy bất kỳ nội dung nào có liên quan. Nó có hợp lệ C++ không? Và nếu vậy, tại sao lỗi clang khi biên dịch nó? Nó là một lỗi trình biên dịch hay nó không thực sự được định nghĩa trong tiêu chuẩn? – Uflex

Trả lời

6

Điều này không được chấp nhận vì C++ 11.

Xem Pointer conversions (tôi nhấn mạnh):

Một con trỏ hằng rỗng (xem NULL), có thể được chuyển đổi sang bất kỳ loại con trỏ, và kết quả là giá trị con trỏ null của loại đó. Chuyển đổi như vậy (được gọi là chuyển đổi con trỏ null) được phép chuyển đổi sang loại có đủ điều kiện là một chuyển đổi, nghĩa là, không được coi là kết hợp của chuyển đổi số và đủ điều kiện.

Lưu ý kể từ C++ 11 một null pointer constant có thể là một số nguyên đen với giá trị zero (hoặc một prvalue loại std::nullptr_t), trong khi false không phải là, đó là một boolean literal.

Và cho đến khi C++ 11 rỗng con trỏ hằng được định nghĩa là một rvalue biểu thức hằng số không thể thiếu của kiểu số nguyên mà đánh giá bằng không, trong khi false là tốt. (GCC sẽ đưa ra một cảnh báo cho nó.)

Từ tiêu chuẩn, $4.10/1 Pointer conversions [conv.ptr] (tôi nhấn mạnh)

Một con trỏ hằng null là một số nguyên đen (2.13.2) với giá trị zero hoặc một prvalue loại std :: nullptr_t.

Việc chuyển một con trỏ null liên tục đến một con trỏ đến cv-trình độ loại là chuyển đổi duy nhất, và không phải là chuỗi các chuyển đổi con trỏ theo sau là một chuyển đổi bằng cấp (4.4).

+3

Lưu ý rằng điều này chỉ áp dụng cho C++ 11 với sự kết hợp [vấn đề 903] (http://open-std.org/JTC1/SC22/WG21/docs/cwg_defects.html#903).Vì C++ 11 ban đầu được xuất bản, hằng số con trỏ null là "một biểu thức hằng số không thể thiếu ...", mà 'false' là. Gần đây tôi đã giải quyết rằng trong [một câu trả lời] (http://stackoverflow.com/a/37214551/1782465). – Angew

+0

@Angew Cảm ơn bạn đã chỉ ra điều đó. – songyuanyao

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