当它注意到具有未定义/未指定/实现定义行为的语句时,编译器是否无法发出警告(如果它抛出错误会更好)?
可能会将语句标记为错误,标准应该这样说,但它至少可以警告编码器。 实施这种方案有任何技术困难吗? 或者它只是不可能?
我得到这个问题的原因是,在a[i] = ++i;
类a[i] = ++i;
陈述中a[i] = ++i;
在达到序列点之前,不会知道代码试图引用变量并在同一语句中修改它。
这一切归结为
对于您的特定示例, gcc
会发出关于“可能未定义”的警告。 它甚至警告printf()
格式不匹配。
但是,如果您希望编译器为所有未定义/未指定的情况发出诊断,则不清楚是否应该/可以工作。
假设您有以下内容:
#include void add_to(int *a, int *b) { *a = ++*b; } int main(void) { int i = 42; add_to(&i, &i); /* bad */ printf("%dn", i); return 0; }
编译器应该警告你*a = ++*b;
线?
正如gf在评论中所说,编译器无法跨翻译单元检查未定义的行为。 经典示例将变量声明为一个文件中的指针,并将其定义为另一个文件中的数组,请参阅comp.lang.c FAQ 6.1 。
gcc在这种情况下会发出警告(至少使用-Wall
):
#include int main(int argc, char *argv[]) { int a[5]; int i = 0; a[i] = ++i; printf("%dn", a[0]); return 0; }
得到:
$ make gcc -Wall main.c -o app main.c: In function 'main': main.c:8: warning: operation on 'i' may be undefined
编辑:
快速阅读手册页显示-Wsequence-point
将执行此操作,如果您由于某种原因不想要-Wall
。
不同的编译器捕获不同的条件; 大多数编译器都有警告级别选项,GCC特别有很多,但是-Wall -Werror会切换大多数有用的编译器,并强制它们出错。 在VC ++中使用 W4 WX进行类似的保护。
在海湾合作委员会你可以使用-ansi -pedantic,但迂腐就是它所说的,并且会引发许多无关紧要的问题,并且很难使用很多第三方代码。
无论哪种方式,因为编译器捕获不同的错误,或者为同一错误产生不同的消息,因此使用多个编译器是有用的,不一定是用于部署,而是作为穷人的静态分析。 C代码的另一种方法是尝试将其编译为C ++; C ++的强类型检查通常会产生更好的C代码; 但请确保如果您希望C编译工作,请不要仅使用C ++编译; 您可能会介绍C ++特定的function。 同样,这不需要部署为C ++,而只是用作额外的检查。
最后,编译器通常在性能和错误检查之间建立平衡; 要详尽检查需要花费很多开发人员不会接受的时间。 出于这个原因,存在静态分析仪,对于C,存在传统的棉绒和开源夹板。 静态分析C ++更复杂,而且工具通常非常昂贵。 我使用过的最好的一个是来自Programming Research的QAC ++。 我不知道任何声誉的任何免费或开源C ++分析器。
相反,编译器不需要对未定义的行为进行任何类型的诊断:
§1.4.1:
可诊断规则集包含本国际标准中的所有语法和语义规则,除了那些包含“不需要诊断” 或被描述为导致“未定义行为”的显式符号的规则。
强调我的。 虽然我同意它可能很好,但编译器在尝试符合标准方面有足够的问题,更不用说教程序员如何编程了。
GCC会在你从语言规范中做出某些事情时尽可能地发出警告,同时仍然在句法上是正确的,但是超出某个特定点时必须足够了解情况。
您可以使用-Wall
标志调用GCC以查看更多内容。
如果您的编译器不会对此发出警告,您可以尝试使用Linter。
Splint是免费的,但只能检查C
Gimpel Lint支持C ++,但售价389美元 – 也许你的公司可以说服购买副本?
以上就是c/c++开发分享未定义/未指定/实现定义的行为警告?相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/560121.html