GCC 编译 warnings

本文详细介绍了GCC编译过程中遇到的各种警告,包括多字符字符常量警告、未定义的操作警告、类型转换警告、可能不返回的函数警告、字符串常量到char*的转换警告、隐式声明函数警告以及严格别名规则警告。并提供了如何消除或处理这些警告的建议,如使用特定的编译选项和修改代码结构。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 编译选项-g:Generate debug information when compiling.

2. 优化选项-O0:关闭所有优化选项。

3. Warning:(GCC)

1) Warning: multi-character character constant

Could be suppressed by -Wno-multichar

There're three kinds of character constants: Normal character constants, Multicharacter constants and Wide-character constants.

    char ch = 'a';
    int mbch = '1234';
    wchar_t wcch = L'ab';


Mbch is of type int(signed), has 4 meaningful characters.

Gcc compiler evaluates a multi-character character constant a character at a time, shifting the previous value left by the number of bits per target character, and then or-ing in the bit-pattern of the new character truncated to the width of a target character.

'ab' for a target with an 8-bit char would be interpreted as:

(int) ((unsigned char) 'a' * 256 + (unsigned char) 'b') = 97*256+98

'1',x          0x31
'12',x        0x3132
'123',x      0x313233
'1234',x    0x31323334

判断系统是big endian还是little endian的方法:

    if (('1234' >> 24) == '1')
    {
        //Little endian
    }
    else if (('4321' >> 24) == '1')
    {
        //Big endian
    }


2) Warning: operation on xx may be undefined

序列点问题。为什么 a[i] = i++; 不能正常工作?子表达式 i++ 有一个副作用,它会改变 i 的值。由于 i 在同一表达式的其它地方被引用,这会导致无定义的结果,无从判断该引用(左边的 a[i] 中)是旧值还是新值。(尽管 在 K&R 中建议这类表达式的行为不确定,但 C 标准却强烈声明它是无定义的),具体实现取决于编译器。

3) Warning: conversion to xxx from yyy may alter its value

Gcc promotes unsigned char/uint16_t/uint8_t  to type int for for all arithmetic. Need to apply static_cast<>.

4) Warning: function might be possible candidate for attribute 'noreturn'

打开了 -Wmissing-noreturn。A few standard library functions, such as abort and exit, cannot return. GCC knows this automatically. With noreturn attribute it can then optimize without regard to what would happen if function ever did return. This makes slightly better code. More importantly, it helps avoid spurious warnings of uninitialized variables. The noreturn keyword does not affect the exceptional path. 给函数加上 __attribute__((noreturn)) 即可消除这个warning。

5)Warning: deprecated conversion from string constant to "char *"

void SomeFunc (char* str)
{
}

int _tmain(int argc, _TCHAR* argv[])
{
    SomeFunc("Hello!");
    return 0;
}


SomeFunc() 的输入时char*,含义是:给我个字符串,我要修改它。而传给它的字面常量是没办法修改的,将char* 改成 const char*,消除这个warning.

 

6) Warning: implicit declaration of function 'malloc'/'free', incompatible implicit declaration of built-in function 'malloc'/'free'

要显示的#include <stdlib.h>

 7) Warning: Dereferencing type-punned pointer will break strict-aliasing rules

打开了-fstrict-aliasing and -Wstrict-aliasing. Suppress with -fno-strict-aliasing

Strict-aliasing rule: An object of one type is assumed never to reside at the same address as an object of a different type, unless the types are almost the same. 编译器希望不同类型的对象不会指向同一个地址。

8) Warning: inlining failed in call to xxx: call is unlikely and code size would grow

打开了-Winline: Warn if a function can not be inlined and it was declared as inline. Even with this option, the compiler will not warn about failures to inline functions declared in system headers.

相关选项:

-fno-inline: Don't compile statement functions inline. Might reduce the size of a program unit--which might be at expense of some speed (though it should compile faster). Note that if you are not optimizing, no functions can be expanded inline.

-finline-functions: Interprocedural optimizations occur. However, if you specify -O0, the default is OFF. Enables function inlining for single file compilation.

 

9) Warning: cannot optimize loop, the loop counter may overflow

打开了-Wunsafe-loop-optimizations: Warn if the loop cannot be optimized because the compiler could not assume anything on the bounds of the loop indices. With -funsafe-loop-optimizations warn if the compiler made such assumptions.

相关选项:

-funsafe-loop-optimizations: Enable unsafe loop optimizations, e.g. assume loop indices never overflow, etc

 

 

### 解决 GCC 编译过程中遇到的警告 当使用 GCC 进行编译时,可能会遇到各种类型的警告。这些警告通常指示潜在的问题或不符合最佳实践的情况。为了处理这些问题,可以采取以下几种策略: #### 修改源代码消除警告 许多警告可以通过修正源代码来解决。例如,未使用的变量会触发 `-Wunused-variable` 警告;此时应该移除不必要的声明或将该变量实际投入使用。 对于特定情况下无法立即修复但又希望忽略某些警告的情形,则可以在函数级别上应用属性宏定义抑制它们的发生。比如下面的例子展示了怎样针对单个函数禁用某个指定类别的警报[^1]: ```c __attribute__((unused)) void my_function() { int unused_variable; // No warning will be generated here. } ``` #### 使用命令行参数控制警告行为 GCC 提供了一系列用于管理警告显示方式及其严重性的开关。常见的有: - `-Wall`: 开启几乎所有有用的警告消息; - `–pedantic`: 严格遵循 ISO C/C++ 标准语法检查,报告任何扩展特性作为警告。 如果只想关闭某一种具体的警告而不是全部的话,也可以借助于专门定制化的标志位实现这一目的。如要屏蔽关于隐式转换可能丢失精度方面的提示可以用到 `-Wno-conversion` 参数[^2]。 #### 查阅官方手册获取更多帮助 除了上述提到的方法之外,还可以查阅 GCC 官方的手册页(`man gcc`) 或者运行 `gcc --help=warnings` 获取更详细的有关可用警告选项的信息列表以及解释说明[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值