2015-07-20 40 views
6

C++ ví dụ sau thất bại trong việc biên dịch với gcc hoặc kêu vang, nhưng chỉ tạo ra một cảnh báo với ICC, và không có gì ở tất cả với MSVC:lỗi: nhảy đến nhãn 'foo' đi qua khởi của 'bar'

int main(int argc, char *argv[]) 
{ 
    if (argc < 2) 
     goto clean_up; 

#if 1 // FAIL 
    int i = 0; 
#elif 0 // workaround - OK 
    { 
     int i = 0; 
    } 
#else // workaround - OK 
    int i; 
    i = 0; 
#endif 

clean_up: 
    return 0; 
} 

g ++:

init.cpp:13: error: jump to label ‘clean_up’ 
init.cpp:4: error: from here 
init.cpp:7: error: crosses initialization of ‘int i’ 

kêu vang ++:

init.cpp:4:9: error: cannot jump from this goto statement to its label 
     goto clean_up; 
     ^
init.cpp:7:9: note: jump bypasses variable initialization 
    int i = 0; 
     ^

ICC:

init.cpp(4): warning #589: transfer of control bypasses initialization of: 
      variable "i" (declared at line 7) 
      goto clean_up; 
     ^

Tôi hiểu nguyên nhân gây ra lỗi, và ví dụ đơn giản như thế này khá dễ làm việc (tôi đã bao gồm một vài giải pháp có thể có trong ví dụ trên), nhưng tôi đang làm việc một cơ sở mã di sản đa nền tảng lớn được xếp chồng lên các macro xử lý lỗi sử dụng cấu trúc goto tương tự. Các nhà phát triển khác làm việc với MSVC hoặc ICC tiếp tục giới thiệu các khởi tạo nội tuyến mà sau đó dẫn đến lỗi cho gcc hoặc clang xây dựng (và tất nhiên họ chỉ bỏ qua các cảnh báo họ nhận được với MSVC/ICC).

Vì vậy, tôi cần phải tìm cách để (a) làm cho các trường hợp này dẫn đến lỗi trên ICC/MSVC hoặc (b) giảm chúng thành cảnh báo bằng gcc/clang. Tôi đã thử -fpermissive với gcc nhưng điều đó dường như không giúp ích gì. Để có thêm tín dụng, tôi cũng tò mò về lý do đằng sau lỗi này để khởi tạo vô hướng đơn giản - tôi có thể thấy lý do tại sao nhảy qua một constructor có thể có vấn đề, nhưng khởi tạo int như trong ví dụ trên dường như không giống như nó có thể là một vấn đề, và chỉ cần tách định nghĩa + khởi tạo thành một định nghĩa + gán làm cho lỗi biến mất?

+0

Trong C, điều này được cho phép (mặc dù được cau mày). Bạn không chắc chắn về C++. – Bathsheba

+1

Nhà phát triển cũng nên khắc phục cảnh báo trình biên dịch của mình, không chỉ lỗi. – Melebius

+0

@Bathsheba: vâng, các macro kế thừa này xuất phát từ cơ sở mã C, nhưng bây giờ mã C++ đang ngày càng được sử dụng và tôi tiếp tục khắc phục từng sự cố mới của vấn đề này. –

Trả lời

2

Cờ MSVC để xử lý cảnh báo là lỗi vi là /we n trong đó n là số cảnh báo.

For example, /we4326 flags warning number C4326 as an error.

Xem https://msdn.microsoft.com/en-us/library/thxezb7y.aspx để biết chi tiết.

+0

Đóng - có vẻ như 'C2362' sẽ là cảnh báo/lỗi thích hợp, nhưng' cl' không tạo ra điều này trừ khi bạn sử dụng '/ Za' có vẻ như, trong trường hợp đó là lỗi. Sử dụng '/ Za' không phải là một lựa chọn không may, vì nó phá vỡ rất nhiều thứ khác. Hmmm ... –

+0

'/ Za' dường như vô hiệu hóa các phần mở rộng của Microsoft của tiêu chuẩn C++. https://msdn.microsoft.com/en-us/library/0k0w269d.aspx Bạn phải quyết định xem có nên sử dụng các phần mở rộng của Microsoft hay biên dịch với GCC… – Melebius

+0

Có, thật không may, '/ Za' vi phạm rất nhiều mã hiện có của chúng tôi (mã biên dịch OK với tất cả các trình biên dịch khác), vì vậy nó không phải là một tùy chọn. Đây là một trong những cơn đau đầu lớn với cơ sở mã kế thừa - bạn không thể "sửa chữa" mọi thứ. –

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