2015-10-22 14 views
7

Tại sao mã sau đây biên dịch mà không có cảnh báo. Lưu ý rằng blablabla() không được xác định ở bất kỳ đâu.Tại sao "std :: string (blablabla());" biên dịch mà không có lỗi?

Tôi đã thử nghiệm nó trong gcc 5.1.0clang-3.7.0 (có và không có cờ -std = C++ 11).

#include <string> 

int main() 
{ 
    std::string(blablabla()); 
} 

câu hỏi này là không một bản sao của gây nhiều tranh cãi nhất phân tích cú pháp mơ hồ, vì ví dụ có liên quan tuyên bố chức năng với một tham số.

+0

Nếu tôi đặt cược đoán, câu lệnh được tối ưu hóa, vì bạn chỉ đơn giản là không sử dụng nó theo bất kỳ cách nào. Bạn không chỉ định chuỗi cho biến và bạn cũng không chuyển nó cho hàm. Như vậy trình biên dịch cũng có thể được 'nhìn' nó. Nhưng đó là một dự đoán. –

+3

Cảnh báo phải độc lập với * bất kỳ * tối ưu hóa nào, trong bất kỳ trình biên dịch gần đây nào. – Kamajii

+0

Err, nếu 'blablabla()' là một hàm thực hiện 'cout <<" Xin chào \ n ";', thì tối ưu hóa đó sẽ hoạt động như thế nào? Tôi chắc chắn bạn không được phép tối ưu hóa mã theo cách mà về cơ bản nó thay đổi hành vi. Trong mọi trường hợp, nó không thực sự * gọi * 'blablabla', không có sự khác biệt giữa câu lệnh đó và một với dấu ngoặc đơn bên ngoài bị loại bỏ. – paxdiablo

Trả lời

8

Ahhhh Tôi câm.

Nó không được coi là cuộc gọi. Trình biên dịch chỉ thấy nó như là một tuyên bố ...

Cố gắng, để so sánh:

int main() { 
    int(blablabla); 
} 

Điều này cho phép:

test.c++: In function ‘int main()’: 
test.c++:6:9: warning: unused variable ‘blablabla’ [-Wunused-variable] 
    int(blablabla); 
     ^

Chính xác hơn, tuyên bố của bạn std::string(blablabla()) tuyên bố blablabla là một hàm trả về an std::string, giống như

std::string blablabla(); 

sẽ làm. Một khai báo hàm cục bộ.

+0

Là int (blablabla); giống như khai báo int blablabla; ? –

+3

Ramana: Có, bạn chỉ cần đặt dấu nhận dạng. Chèn một dấu cách và nó sẽ rõ ràng hơn: 'int (((((blablabla))));'.Btw, cũng có trường hợp các dấu ngoặc đơn thậm chí còn cần thiết, cụ thể là khi khai báo con trỏ chức năng (để gắn dấu sao vào mã định danh và không phải kiểu trả về). – Kamajii

+0

@Ramana Có, đầu mối là nó cảnh báo rằng biến 'blablabla' không được sử dụng. – skyking

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