C++ 导致编译器发出虚假警告的场景有哪些?

C++ 导致编译器发出虚假警告的场景有哪些?,c++,c,compiler-construction,C++,C,Compiler Construction,我有时在源代码中读到以前的开发人员的评论: // and this is to make compiler stop crying 我认为使用C/C++时,您所做的事情通常是合法的,但编译器仍然认为它是非法的 有没有导致编译器发出虚假警告的场景列表?我想到的最明显的例子是gcc警告: while (i = somefunc()) 您可以使用特定的复活节彩蛋来抑制警告: while ((i = somefunc())) 当然,假设警告不正确,并且您不是有意写: while (i == som

我有时在源代码中读到以前的开发人员的评论:

// and this is to make compiler stop crying
我认为使用C/C++时,您所做的事情通常是合法的,但编译器仍然认为它是非法的


有没有导致编译器发出虚假警告的场景列表?

我想到的最明显的例子是gcc警告:

while (i = somefunc())
您可以使用特定的复活节彩蛋来抑制警告:

while ((i = somefunc()))
当然,假设警告不正确,并且您不是有意写:

while (i == somefunc())

但这在很大程度上取决于您的编码风格,您将在无错误代码中触发哪些警告。有些人,诚然是一小部分C程序员,从一开始就不会在条件中进行赋值,因此对他们来说,这个警告不是“虚假的”,因为如果他们得到了它,那么它总是因为键入了
==

我想到的最明显的例子是gcc警告:

while (i = somefunc())
您可以使用特定的复活节彩蛋来抑制警告:

while ((i = somefunc()))
当然,假设警告不正确,并且您不是有意写:

while (i == somefunc())

但这在很大程度上取决于您的编码风格,您将在无错误代码中触发哪些警告。有些人,诚然是一小部分C程序员,从一开始就不会在条件中赋值,所以对他们来说,这个警告不是“虚假的”,因为如果他们得到了它,那么它总是因为键入了
==

没有明确的警告列表,因为C标准不允许符合标准的编译器为法律代码发出警告或诊断消息。因此,每个C编译器都有自己的警告列表,其中一些警告可以在完全正确、完全合法的代码上触发(这方面的规范示例是一个带有从未使用过的参数的函数)

这意味着抑制此类警告的代码更改通常针对特定的编译器(甚至可能是该编译器的特定版本),并且通常通过反复试验发现,而不是提前预期


然而,有时,这样的代码修改实际上是使代码正确-被抑制的编译器诊断是C标准所要求的。通常的例子是赋值中需要强制转换——例如,不能将整数值赋值给指针对象,但大多数编译器都会发出警告并编译代码。在这种情况下添加强制转换会使警告静音,因为它会更正代码-警告根本不是虚假的。

没有此类警告的明确列表,因为C标准不允许符合要求的编译器发出警告或法律代码诊断消息。因此,每个C编译器都有自己的警告列表,其中一些警告可以在完全正确、完全合法的代码上触发(这方面的规范示例是一个带有从未使用过的参数的函数)

这意味着抑制此类警告的代码更改通常针对特定的编译器(甚至可能是该编译器的特定版本),并且通常通过反复试验发现,而不是提前预期


然而,有时,这样的代码修改实际上是使代码正确-被抑制的编译器诊断是C标准所要求的。通常的例子是赋值中需要强制转换——例如,不能将整数值赋值给指针对象,但大多数编译器都会发出警告并编译代码。在这种情况下添加强制转换会使警告静音,因为它会更正代码-警告根本不是虚假的。

程序员可能会编写这样的注释的一种情况是,编译器发现的问题实际上是不可能的,但编译器无法确定这一事实。例如:

int foo(char *barArg) {
    char *barPtr, *grillPtr;
    if (barArg == NULL) {
        grillPtr = malloc(...);      /* allocate */
        get_default_bar(grillPtr);   /* initialize */
        barPtr = grillPtr;
    } else {
        barPtr = barArg;
    }

    /* Some common block of processing that does _not_ refer to grillPtr,
     * does _not_ assign to barArg, and _updates_ barPtr. */

    if (barArg == NULL) {
        free(grillPtr);              /* <<<----- here */
    }
    return 0;
}
intfoo(char*barArg){
char*barPtr,*grillPtr;
if(barArg==NULL){
grillPtr=malloc(…);/*分配*/
获取默认工具栏(grillPtr);/*初始化*/
barPtr=格栅PTR;
}否则{
barPtr=barArg;
}
/*一些不涉及GRIGLLPTR的常见处理块,
*不分配给barArg,并且更新barPtr*/
if(barArg==NULL){

free(grillPtr);/*程序员可能编写此类注释的一种情况是,编译器发现的问题实际上是不可能的,但编译器无法确定这一事实。例如:

int foo(char *barArg) {
    char *barPtr, *grillPtr;
    if (barArg == NULL) {
        grillPtr = malloc(...);      /* allocate */
        get_default_bar(grillPtr);   /* initialize */
        barPtr = grillPtr;
    } else {
        barPtr = barArg;
    }

    /* Some common block of processing that does _not_ refer to grillPtr,
     * does _not_ assign to barArg, and _updates_ barPtr. */

    if (barArg == NULL) {
        free(grillPtr);              /* <<<----- here */
    }
    return 0;
}
intfoo(char*barArg){
char*barPtr,*grillPtr;
if(barArg==NULL){
grillPtr=malloc(…);/*分配*/
获取默认工具栏(grillPtr);/*初始化*/
barPtr=格栅PTR;
}否则{
barPtr=barArg;
}
/*一些不涉及GRIGLLPTR的常见处理块,
*不分配给barArg,并且更新barPtr*/
if(barArg==NULL){

free(grillPtr);/*编译器警告那些正式合法的事情,但他们认为这可能是一个错误,比如
if(i=0)
。我不明白为什么要关闭它。这个问题是完全可以解释和回答的。投票重新打开。“我们能有一个X的列表吗?”是不可回答的。@Nicol Bolas:我认为这完全是主观的。C编译器能够并且确实发出警告,不管他们想要什么完全合法的代码,这一事实远非显而易见。我认为,关于禁止警告的更改实际上使代码正确的情况,还有一个有用的讨论(以前没有的时候)。@Nicol Bolas:在我看来,答案“这样的列表无法创建,原因如下:”使其成为一对完全有用的问答组合。这里最有用的答案是提供