12

Khi bạn biên dịch C++ file nguồn sau trong Visual Studio 2010 với mức cảnh báo/W4 kích hoạtVisual Studio 2010 (C++): ngăn chặn C4706 cảnh báo tạm thời

#include <cstdio> // for printf 
#include <cstring> // for strcmp 

char str0[] = "Hello"; 
char str1[] = "World"; 

int main() 
{ 
    int result; 

    if (result = strcmp(str0, str1)) // line 11 
    { 
     printf("Strings are different\n"); 
    } 
} 

bạn nhận được cảnh báo sau đây

cảnh báo C4706: chuyển nhượng trong biểu thức có điều kiện

cho dòng 11.

Tôi muốn chặn cảnh báo này chính xác tại địa điểm này. Vì vậy, tôi đã cố gắng Google và tìm thấy trang này: http://msdn.microsoft.com/en-us/library/2c8f766e(v=VS.100).aspx

Vì vậy, tôi đã thay đổi mã như sau - hy vọng điều này sẽ giải quyết vấn đề:

#include <cstdio> // for printf 
#include <cstring> // for strcmp 

char str0[] = "Hello"; 
char str1[] = "World"; 

int main() 
{ 
    int result; 

#pragma warning(push) 
#pragma warning(disable : 4706) 
    if (result = strcmp(str0, str1)) 
#pragma warning(pop) 
    { 
     printf("Strings are different\n"); 
    } 
} 

Nó không giúp đỡ.

biến thể này không giúp được gì:

#include <cstdio> // for printf 
#include <cstring> // for strcmp 

char str0[] = "Hello"; 
char str1[] = "World"; 

int main() 
{ 
    int result; 

#pragma warning(push) 
#pragma warning(disable : 4706) 
    if (result = strcmp(str0, str1)) 
    { 
#pragma warning(pop) 
     printf("Strings are different\n"); 
    } 
} 

Để tránh một cuộc điều tra thêm: Tôi làm sạch các giải pháp trước mỗi biên dịch. Vì vậy, đây có lẽ không phải là lỗi.

Vì vậy, trong kết luận: làm thế nào để loại bỏ C4706 chính xác ở nơi này?

Chỉnh sửa Có, viết lại là có thể - nhưng tôi thực sự muốn biết tại sao cách tôi cố gắng ngăn chặn cảnh báo (được ghi lại chính thức trên MSDN) không hoạt động - lỗi ở đâu?

Trả lời

14

Trong MSDN Libray: http://msdn.microsoft.com/en-us/library/2c8f766e(v=VS.100).aspx, có phần như sau.

Đối với số cảnh báo trong khoảng 4700-4999, đó là những người gắn liền với thế hệ mã, tình trạng cảnh báo có hiệu lực khi trình biên dịch gặp nẹp xoăn mở của một hàm sẽ có hiệu lực cho phần còn lại của hàm. Sử dụng pragma cảnh báo trong chức năng thay đổi trạng thái cảnh báo có số lớn hơn so với 4699 sẽ chỉ có hiệu lực sau khi kết thúc hàm. Ví dụ sau cho thấy vị trí chính xác của cảnh báo pragmas thành vô hiệu hóa thông báo cảnh báo tạo mã và sau đó khôi phục nó.

Vì vậy, '#pragma warning' chỉ hoạt động cho mỗi chức năng/phương pháp.

Vui lòng xem mã sau để biết thêm chi tiết.

#include <cstdio> // for printf 
#include <cstring> // for strcmp 

char str0[] = "Hello"; 
char str1[] = "World"; 

#pragma warning(push) 
#pragma warning(disable : 4706) 
void func() 
{ 
    int result; 
    if (result = strcmp(str0, str1)) // No warning 
    { 
     printf("Strings are different\n"); 
    } 
#pragma warning(pop) 
} 

int main() 
{ 
    int result; 

    if (result = strcmp(str0, str1)) // 4706 Warning. 
    { 
     printf("Strings are different\n"); 
    } 
} 
8

Các giải pháp lành mạnh là phải viết lại điều kiện để

if((result = strcmp(str0, str1)) != 0) 

đó sẽ thông báo cho bất kỳ C biên dịch mà bạn thực sự muốn chuyển nhượng, là gần như chắc chắn để tạo mã cùng một đối tượng.

+2

Hầu hết các trình biên dịch thực hiện "bạn có chắc" yếu tố bằng cách yêu cầu một cặp thêm dấu ngoặc, tôi muốn MSVC có thể làm như vậy. – Thomas

19

Thay vì cố gắng ẩn cảnh báo của bạn, hãy sửa the issue it's complaining about; bài tập của bạn có một giá trị (giá trị ở phía bên trái của bài tập) có thể được sử dụng hợp pháp trong một biểu thức khác.

Bạn có thể khắc phục điều này bằng cách kiểm tra một cách rõ ràng là kết quả của sự phân công:

if ((result = strcmp(str0, str1)) != 0) 
{ 
    printf("Strings are different\n"); 
} 
+0

Tôi không thể tin rằng tôi không nghĩ về điều đó. Cảm ơn bạn! Giải pháp tốt nhất. –

1

Có một cấu trúc đơn giản !! để đúc loại bool. Như thế này:

if (!!(result = strcmp(str0, str1))) 

Tuy nhiên, trong một số trường hợp, so sánh trực tiếp != 0 có thể rõ ràng hơn với người đọc.

2

Có một giải pháp khác tránh cảnh báo: comma operator.

Lợi thế chính ở đây là bạn không cần dấu ngoặc đơn nên ngắn hơn một chút so với giải pháp !=0 khi tên biến của bạn ngắn.

Ví dụ:

if (result = strcmp(str0, str1), result) 
{ 
    printf("Strings are different\n"); 
} 
Các vấn đề liên quan