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?
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
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
@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. –