Tag: 编译器 警告

为什么GCC在这个例子中没有发出警告

启用-Wsequence-point ,GCC应在发现未定义的行为代码时警告用户。 例如 b = a + ++a; 应该被GCC注意到并且应该被报告为“未定义的行为”代码(因为ISO C没有指定评估操作数的顺序)。 但是,我玩了语法,我尝试了这个: int *a = malloc(sizeof(int) * 2); a[0] = 1; printf(“%d\n”, *(a + (*a)++ – *a)); 当然,我收到了警告 警告:’* a’上的操作可能未定义[-Wsequence-point] 这是我所期望的,因为*a (其为a[0] )的值可以在处理第三个操作数时递增或者可以不递增。 但是,我尝试了以下一个: int *a = malloc(sizeof(int) * 2); a[0] = 1; printf(“%d\n”, *(a + (*a)++ – 1)); 我很惊讶,因为我没有收到任何警告。 这不应该是UB吗? 我的意思是,根据ISO C99,可以在表达式评估期间的任何点评估后增量操作(逗号运算符和三元运算符除外)。 在我的后一个例子中,我没有递增指针,而是指向它指向的整数。 因此,根据标准,它可以在任何点递增(这意味着它可以在评估整个表达式后递增),因此程序可以打印1或2 ,对吧? […]

使用类型转换删除gcc编译器警告

我正在使用gcc 4.9进行嵌入式ARM编程。 我一直在使用-Wconversion开关,因为它在我公司的默认开发工具配置中。 我正在使用stdint.h 类型 (uint8_t,uint32_t等)。 每次执行复合赋值或简单添加时,编译器都会创建警告。 例如: uint8_t u8 = 0; uint16_t u16; // These cause warnings: u8 += 2; u8 = u16 >> 8; 修复此问题的“常用方法”是使用强制转换,如此处和此处所述 : u8 = (uint8_t)(u8 + 2); u8 = (uint8_t)(u16 >> 8); 除了这个丑陋之外,我还在不断地遇到令人信服的证据,certificate施法通常是不好的做法。 我的问题: 为什么以这种方式使用类型转换是不好的? 通过简单地省略-Wconversion并让编译器为我做隐式转换,我会失去什么吗?

如何明智地解释这个编译器警告?

当我执行这个问题的代码时,我得到了这个警告: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘long int’ [-Wformat=] printf(“PQ: %d, P: %d, Q: %d”, (p – q), p, q); ~^ ~~~~~~~ %ld 作为reflection修复,我使用%ld来打印两个指针的减法。 编制者同意了。 幸运的是,我看到另一位用户提到应该使用%td的评论,因为减法的结果类型是ptrdiff_t 。 这个答案证实了这一说法。 现在从GCC的stddef.h头文件中,我可以看到这些类型在这种情况下是等价的: typedef __PTRDIFF_TYPE__ ptrdiff_t; #define __PTRDIFF_TYPE__ long int 但是,我只是建议对OP的错误(或多或少)修复,使用%ld而不是%td 。 有没有办法让我理解单独的编译器警告是不够的? 或者也许明智地解释警告本身,而不仅仅是反应。