2014-08-29 70 views
13

Các mã sau đây tạo ra cảnh báo C4127 (biểu thức điều kiện là không đổi) trong Visual Studio 2010 (nơi alias_wchar_t là một bí danh cho wchar_t):C4127: biểu thức điều kiện là liên tục

if (sizeof(alias_wchar_t) == sizeof(wchar_t)) // warning occurs here 
{ 
    // do stuff 
} 
else 
{ 
    // do other stuff 
} 

cách thanh lịch nhất để giải quyết này là gì , ngăn chặn cảnh báo?

Giải pháp tốt nhất mà tôi đã đưa ra là xếp thứ tự có điều kiện vào một bool tĩnh và sử dụng điều đó làm điều kiện. Có một số lượng tốt của mã ở trên và dưới if-else, vì vậy tôi quấn toàn bộ điều trong niềng răng để giới hạn phạm vi của biến càng nhiều càng tốt:

// <snip> 

{ 
    static bool isSameSize = (sizeof(alias_wchar_t) == sizeof(wchar_t)); 
    if (isSameSize) 
    { 
     // do stuff 
    } 
    else 
    { 
     // do other stuff 
    } 
} 

// <snip> 

Điều này cảm thấy khá thô mặc dù. Điều này có vẻ như nó phải được giải quyết tại thời gian biên dịch chứ không phải là thời gian chạy, nhưng bộ tiền xử lý không biết về sizeof. Có cách nào sạch hơn, thanh lịch hơn để giải quyết vấn đề này không?

+1

lưu ý: C++ 17 đang xem xét một cái gì đó như 'nếu constexpr' sẽ giải quyết vấn đề này –

Trả lời

5

Dường như bạn biết điều gì đang xảy ra và bạn ổn với điều này.

Compiler pragma s có nghĩa là đối với trường hợp như thế:

__pragma(warning(push)) 
__pragma(warning(disable:4127)) 
if (sizeof(alias_wchar_t) == sizeof(wchar_t)) { 
__pragma(warning(pop)) 
} 

Về cơ bản, bạn đang nói với trình biên dịch (và thậm chí quan trọng hơn, để độc giả nhân mã của bạn) mà bạn đã xem xét các cảnh báo, và đó Bạn biết những gì bạn đang làm.

+4

Cá nhân tôi nghĩ rằng giải pháp ban đầu của Christopher Berman là tốt hơn. Pragmas là trình biên dịch cụ thể và quá chi tiết. –

2

Đây là những gì tôi đã đưa ra. Nó không gây ra bất kỳ cảnh báo nào trong Microsoft Visual Studio 2013 và nó không yêu cầu bạn sử dụng các Pragmas cụ thể của Visual C++.

Đầu tiên xác định lớp mẫu sau.

template <bool b> 
struct condition 
{ 
    static bool test() 
    { 
     return true; 
    } 
}; 
template <> 
struct condition<false> 
{ 
    static bool test() 
    { 
     return false; 
    } 
}; 

Sau đó, sử dụng như sau.

if (condition<sizeof(alias_wchar_t) == sizeof(wchar_t)>::test()) 

Tôi có ý tưởng từ C++ 14 std :: có điều kiện được mô tả tại http://en.cppreference.com/w/cpp/types/conditional.

5

Cách thanh lịch nhất để giải quyết vấn đề này, ngăn chặn cảnh báo là gì?

Điều kiện này được biết tại thời gian biên dịch, vì vậy bạn có thể thực hiện kiểm tra tại thời gian biên dịch. Không sử dụng một if, chỉ cần cho trình biên dịch chèn một cuộc gọi đến đúng chức năng. Dưới đây là một ví dụ hoàn chỉnh:

#include <iostream> 

typedef short alias_wchar_t; // for testing 

template<bool Condition> 
struct DoStuff 
{ 
}; 

template<> 
struct DoStuff<true> 
{ 
    static void doStuff() 
    { 
     std::cout << "sizeof(alias_wchar_t) == sizeof(wchar_t)\n"; 
    } 
}; 

template<> 
struct DoStuff<false> 
{ 
    static void doStuff() 
    { 
     std::cout << "sizeof(alias_wchar_t) != sizeof(wchar_t)\n"; 
    } 
}; 

void doStuff() 
{ 
    DoStuff<sizeof(alias_wchar_t) == sizeof(wchar_t)>::doStuff(); 
} 

int main() 
{ 
    doStuff(); 
} 

Cho dù đó là thực sự thanh lịch hơn mã ban đầu của bạn (với điều đó cảnh báo trình biên dịch đặc biệt tắt cho đơn vị biên soạn này) là dựa vào ý kiến, tôi muốn nói.

Trong mọi trường hợp, điều này biên dịch với không có cảnh báo tại /W4 với VC năm 2013.

+0

bạn không nghĩ rằng bạn vừa tăng gấp đôi số lượng mã cho mantain;) –

+0

@AlexanderEnaldiev: Độ dài mã không phải là yếu tố duy nhất xác định mức độ dễ dàng của một thứ có thể được duy trì. Như tôi đã nói ở đây cách đây hơn hai năm, cho dù nó thanh lịch hay không phụ thuộc vào ngữ cảnh thực tế của mã. –

+0

Không thể đồng ý với bạn. Nó có thể là vô nghĩa. Giả sử mẫu struct Foo { bool Check() { bool retval = checkImpl(); nếu (Nghiêm ngặt) retval = retval && checkStrict(); trả lại trả lại; } }; Tôi có C4127 ở đây? Bạn không nghĩ rằng, tôi khá chắc chắn rằng liên tục phụ thuộc vào mẫu arg? Hoặc điểm C4127 là gì. Nó bày tỏ điều gì? Không thể tìm ra được. Bất kể nhiều năm trôi qua;) –

1

Nếu nó chỉ là một biểu hiện thường xuyên sau đó sử dụng:

typedef wchar_t alias_wchar_t; 
bool constExpression = sizeof(alias_wchar_t) == sizeof(wchar_t); 
if (constExpression) // potential warning 
{ 
    // do stuff 
} 
else 
{ 
    // do other stuff 
} 

Dường như c4127 được tạo ra bởi các chỉ hành động đánh giá một biểu thức liên tục trong câu lệnh điều khiển.

+0

Tôi đã sử dụng biến thể này với thành công: constexpr bool constExpression = sizeof (alias_wchar_t) == sizeof (wchar_t); if (constExpression) {} –

3

Một cách khác để tắt cảnh báo là tạo một chức năng nhận dạng giả và sử dụng nó trên một trong các hằng số.

// Define this somewhere 
template<typename T> const T& identity(const T& t) { return t; } 

... 

// NB: 'identity' used only to remove "warning C4127" 
if (identity(sizeof(alias_wchar_t)) == sizeof(wchar_t)) 
{ 
    // do stuff 
} 
else 
{ 
    // do other stuff 
} 

Điều này không hoàn hảo nhưng có vẻ nhẹ hơn các giải pháp khác và có thể tái sử dụng cho các loại hằng số khác nhau.

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