VC++ 编译器:如何确定当前警告级别或覆盖?
我有一个项目,我刚刚发现警告 C4244(可能丢失数据)被抑制。 我强烈怀疑某些糟糕的 MS 标头会抑制此警告,并使其对包含所述标头的所有翻译单元都被抑制,但我还没有确定它们的无数标头中的哪一个可能有问题。
因此,像任何其他编程问题一样,我想首先进行二进制搜索,打印出当前的警告级别,如果可能的话,在我的主预编译头中打印出任何受抑制的警告。
有谁知道我可能使用什么编译器指令,或者我可以采取什么方法来给我这些信息?
我无法告诉你,当调用者违反约定并尝试向我发送一个整数而不是有符号字节时,发现我在标头中精心构造的类型声明未能给出编译器警告是多么令人讨厌(这导致了我正在尝试解决当前的错误)。
想法?
注意:
在我的整个解决方案中搜索 #pragma 时,只得到 #pragma warning(disable:xxxx) 的平衡声明,后跟 #pragma warning(default:xxxx)。 这些都没有引用 4244。
在整个解决方案中搜索 4244 不会返回任何匹配项(我从未覆盖该警告,我包含的任何库、子项目等也没有覆盖该警告)。
在整个 MS 中对 4244 的搜索包括返回一些引用的路径,这些引用似乎是平衡的,或者几乎是平衡的,具体取决于调用它们之前设置的 #define 符号。 因此我怀疑微软有错(结合微软之前在标题中做草率工作的历史)。
I've got a project where I've just discovered that warning C4244 (possible loss of data) is being suppressed. I strongly suspect that some crummy MS header is suppressing this warning and leaving it suppressed for all translation units that include said header, but I've not determined which of their myriad headers may be at fault.
So, like any other programming problem, I'd like to start by doing a binary search, printing out the current warning level and if possible any suppressed warnings in my main Pre Compiled Header.
Does anyone know what compiler directive I might use, or what approach I might be able to take that would give me that information?
I cannot tell you how obnoxious it is to find that my carefully constructed type declarations in my headers are failing to give a compiler warning when a caller violates the contract and tries to send me an integer instead of a signed byte (which has led to the current bug I'm trying to solve).
Thoughts?
NOTES:
Searches on #pragma through my entire solution come up with only balanced declarations of #pragma warning(disable:xxxx) followed by #pragma warning(default:xxxx). And none of those reference 4244.
Searches on 4244 throughout the entire solution return no matches (I never override that warning, nor do any of my included libraries, sub-projects, etc.).
Searches on 4244 throughout the entire MS include paths return a few references, that appear to be balanced, or almost so, depending on the #define symbols that were set before calling them. Hence my suspicion that MS is at fault (combined with prior history of MS doing sloppy work in their headers).
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
添加此
另一种选择是在文件顶部紧接着
#include
s这会将警告重置为默认值,并丢弃任何可能已调用的忽略。
另一方面,我发现 Microsoft 标头不太可能禁用警告。
Another option is to add this
at the top of the file right after the
#include
sThis resets the warning to the defualt, discarding any ignore which might have been called.
On a different note, I find it highly unlikely that an Microsoft header would disable a warning.
您可以在所有头文件中搜索“C4244”,还是只能访问预编译的头文件?
Can you just do a search through all the header files for "C4244" or do you only have access to pre-compiled header files?
您可以首先使用 /P 编译器命令行选项< /a>. 它将预处理器的输出输出到文件。 这样,您实际上可以确保它确实是一个添加警告禁用的标头,并尝试收集一些关于它可能是哪个标头的提示。
You can start with using the /P compiler command line option. It outputs to a file the output of the preprocessor. this way you can actually make sure that its really a header that adds the warning disable and try to gather some hints as to which header it might be.
经过进一步调查:
/P 花费的时间太长(我从未见过它在近一个小时的过程中超出了几个文件,因此我取消了该构建)
我始终无法找到一种明确的方法来打印当前的内容警告级别是,或在编译中的给定点有效的任何覆盖。 所以我问的问题并没有得到真正的回答,除非 /P 参数实际上对你有用(正如我提到的,这对我的目的来说是不切实际的)。
我能够做的是在各个标头中构造一些内联调用,如果警告级别包括该警告为活动状态,则应生成必要的警告,以验证该警告是否处于活动状态:
inline int test(char value) {返回++值; }
包含“某事”
内联 int test1(int value) { return test(value); } // 应该生成 C4244 - 如果前面的 #include 没有弄乱警告级别或覆盖警告 4244,则可能会丢失数据。
依此类推...
最后,我发现 4244 特别有一些奇怪的地方与其相关的规则,并且除了 /W4(警告级别 4)(最高警告级别)之外,它实际上被“禁用”。 由于该警告级别非常非常敏感,并且抱怨很多远远超出我们处理范围的事情,因此我不想启用 /W4。
相反,我所做的是将以下内容放入 stdafx.h PCH 中:
pragma warning(error:4244) // 这完全启用了对所有情况下由于隐式类型转换而可能发生的数据丢失的警告,无论有效的警告级别如何
。
因此,MS 没有在影响我们的任何文件中留下不平衡的警告覆盖。 只是 4244 非常宽容,除非在最高警告级别,无论如何,它对我们真正有用。
感谢您的帮助!
After further investigation:
/P takes too long (I never witnessed it getting beyond a few files over the course of nearly an hour, so I canceled that build)
I was never able to find a clear-cut way to print out what the current warning level was, or any overrides that were in effect at a given point in compilation. So the question I asked is not really answered, unless the /P argument actually is useful to you (as I mentioned, it was impractical for my purposes).
What I was able to do was to construct some inline calls in the various headers that should generate the requisite warning if the warning level included that warning as active, to verify if that warning was active or not:
inline int test(char value) { return ++value; }
include "something"
inline int test1(int value) { return test(value); } // should generate C4244 - possible loss of data if the previous #include didn't mess up the warning level or override warning 4244.
And so on...
In the end, what I discovered was that 4244 in particular has some odd rules associated with it, and that it is effectively "disabled" in all but /W4 (warning level 4) - the highest warning level. Since that warning level is very, very touchy and complains about lots of things that are well beyond our scope of doing anything about them, I didn't want to enable /W4.
What I did instead was to put the following in our stdafx.h PCH:
pragma warning(error:4244) // this fully enables warnings for possible data loss due to implicit type conversion in all circumstances regardless of the active warning level
That worked.
So, MS did not leave unbalanced warning overrides in any of their files that affected us. It was just that 4244 is very forgiving except at the highest warning level, where it becomes truly useful to us, anyway.
Thanks for your help!