c - 如果我使用“=+”而不是“+=”运算符,是否可以让 GCC 警告我?
问题描述
例如:
#include <stdio.h>
#define TS_SIZE 188
int main(void)
{
volatile int offset = 0;
volatile int len = 10;
for (int i=0; i < len; i++)
{
offset =+ TS_SIZE; /* This should be += */
}
printf("Offset: %d \n", offset);
return 0;
}
即使在 Godbolt 编译器资源管理器上使用最新的 GCC (10.x) 也尝试过 "和" -Wall
,但运气不佳。-Wextra
-pedantic
注意:这只是一个人为的小示例代码。出于显而易见的原因使用挥发性物质。
解决方案
这实际上不是编译器的工作。那里有一个编译器来检查您的代码是否是有效的 C,然后将您的源代码转换为目标系统的机器代码。
然而,编译器多年来变得越来越友好,有时会警告常见错误、定义不明确的行为或其他潜在的运行时不当行为。这种友好性不应该被误认为是编译器会捕获所有此类错误的保证。
虽然编译器倾向于对 发出警告if(a = b)
,但带有最大警告的 gcc 甚至不会对明显的事情发出警告,例如int arr[2]; arr[2]=1;
(clang 和 icc 会发出警告)。正如您所注意到的,也不是 for=+
等=!
。
解决方案是拥有一个涵盖尽可能多已知问题的软件质量系统。不仅仅依靠编译器警告,而是迈出成为专业软件工程师的一步。这意味着编码风格指南、使用 C 的安全子集的编码标准、静态分析工具、代码“美化器”和同行代码审查。
静态分析器可以找到很多编译器不寻找的错误,但可能不是这个特定的错误,除非你明确地配置它来寻找它。编码标准 + 代码美化器应该将代码转换为offset = +TS_SIZE;
,然后手动代码审查将很容易发现错误。
编辑:正如评论中所指出的,在=+
K&R 之前的早期版本中曾经是有效的 C。这里有一些历史教训:=+ 在 C 中是什么意思?,请特别参阅 Jonathan Leffler 的出色回答。
推荐阅读
- r - 如何使用定期拆分的时间数据重构数据帧(并计算更新的持续时间)
- java - 如何使用 Spring Boot 中的特定日期范围和聚合从 MongoDB 数据库中检索数据?
- reactjs - 自动完成在 IDE WebStorm 内的 ReactJs 插值大括号内不起作用
- c# - TreeView 不填充节点
- c# - 仅替换之前指定字符串和之后指定字符串的子字符串
- mysql - 使用两个 group by 和一个基本 tri-table 多对多模式的计数进行查询
- java - Appium 会话在同一设备上并行执行
- prolog - 如何在序言中从字符串中修剪正确的空格?
- python - 忽略 BeautifulSoup 中具有相同类的两个 div 中的第一个
- java - spring mvc(版本 5)可以用 cucumber 放心吗?