我有一个C++项目,可以在x86 Linux和Windows上使用gcc 7.2进行构建,并且没有警告,我需要将它移植到ARM设备上,所以我尝试使用运行在我的"arm-linux-gnueabihf"gcc 7.2交叉编译它x86机器,它构建但我得到了很多这种警告
note: parameter passing for argument of type '__gnu_cxx::__normal_iterator<P2d*, std::vector<P2d> >' changed in GCC 7.1
_M_realloc_insert(end(), __x);
Run Code Online (Sandbox Code Playgroud)
和
/opt/armv7-gcc-2017/arm-linux-gnueabihf/include/c++/7.2.0/bits/vector.tcc:105:21: note: parameter passing for argument of type '__gnu_cxx::__normal_iterator<cpzparser::Anchor*, std::vector<cpzparser::Anchor> >' changed in GCC 7.1
_M_realloc_insert(end(), std::forward<_Args>(__args)...);
Run Code Online (Sandbox Code Playgroud)
要么
/opt/armv7-gcc-2017/arm-linux-gnueabihf/include/c++/7.2.0/bits/vector.tcc:394:7: note: parameter passing for argument of type 'std::vector<cpzparser::PointEntity>::iterator {aka __gnu_cxx::__normal_iterator<cpzparser::PointEntity*, std::vector<cpzparser::PointEntity> >}' changed in GCC 7.1
vector<_Tp, _Alloc>::
Run Code Online (Sandbox Code Playgroud)
生成的可执行文件似乎工作正常,但我担心所有这些警告的存在,因为我不知道他们的意思..任何线索?
较新版本的gcc提供了Wimplicit-fallthrough,这对于大多数switch语句都很有用.但是,我有一个switch语句,我希望允许所有case语句的掉头.
有没有办法明确地通过?我宁愿避免Wno-implicit-fallthrough为这个文件编译.
编辑:我正在寻找一种方法来通过显式(如果可能)使下降,而不是通过编译器开关或编译指示关闭警告.
void operator"" test( const char* str, size_t sz )
{
std::cout<<str<<" world";
}
int main()
{
"hello"test;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
在GCC 4.7中,这会生成"警告:未在'_'之前的文字运算符后缀保留用于将来的标准化[默认启用]"
我理解为什么会产生这个警告,但是GCC说"默认启用".
是否可以在不通过-w标志禁用所有警告的情况下禁用此警告?
我们想要开始使用-Wall -Werror大型项目.
由于尺寸的原因,这种变化必须分阶段进行,我们首先要从最重要的警告开始.
最好的方法似乎是使用-Wall -Werror,特殊警告的例外情况.特别的警告是我们有很多(因此修复所有这些都很难和冒险),我们认为它们不是很危险.
我不是说我们不想解决所有这些警告 - 只是没有在第一阶段.
我知道有两种方法可以排除警告-Werror- 最好的是-Wno-error=xxx,如果它不起作用 - -Wno-xxx(当然,我们更愿意看到警告并忽略它,而不是隐藏它).
我的问题是默认情况下启用的警告,并且没有-Wxxx与它们相关的标志.使用时我找不到任何方法来全部使用它们-Werror.
我特别关注两个具体的警告.这是一个展示它们和编译器输出的程序:
#include <stdio.h>
void f(int *p) { printf("%p\n", p); }
int main(int argc, char *argv[]) {
const int *p = NULL;
const unsigned int *q = NULL;
f(p); /* Line 7: p is const, f expects non const */
if (p == q) { /* Line 8: p is signed, q is unsigned */ …Run Code Online (Sandbox Code Playgroud) 我有一个10岁以上的C库 - 我相信 - 曾经在过去的好日子里工作得很好,但是当我尝试将它与C++源码(包含主要功能)一起使用时,有一天我遇到了有些困难.
编辑:澄清一下,C库编译得很好gcc,它会生成一个目标文件old_c_library.o.该库被认为在某种程度上,这样的C头文件中使用的old_c_library.h是#include在D main.cC源文件.然后你的主要C源文件应该编译并与old_c_library.ovia 链接在一起gcc.在这里,我想使用C++源文件main.cpp,并编译/链接它g++.
在编译C++源文件期间发生了以下三个问题:
new(它是一个整数的名称),导致致命错误; 和calloc调用(缺少显式类型转换),导致致命错误; 和编辑:我试图使用#extern "C" { #include "obsolete_c_library.h" }"技巧",如评论中所建议,但这并没有解决我的任何问题.
我可以通过重命名保留字的所有实例并用 - 基本上 - 替换它们来解决问题1.我可以通过类型化calloc调用来解决问题2 .我可能会尝试通过这里建议的想法来解决警告:如何禁用几行代码的GCC警告.
但我仍然想知道,有没有办法以优雅,高层次的方式克服这些困难,而不是真正触及原始图书馆?
在一些C99代码,我需要检查变量是否i是在间隔[0, max],其中max已知是正的.问题是变量的类型允许有符号和无符号(通过更改a typedef).如何最好地检查变量是否在区间内?
直截了当的方法是:
bool is_in_interval(my_type i, my_type max) {
assert(max > 0);
return (i >= 0 && i <= max);
}
Run Code Online (Sandbox Code Playgroud)
当我们有时,这将正常工作typedef int my_type;.但是当my_type无符号(即typedef unsigned int my_type;)时,i >= 0总是如此,编译器会(正确地)警告它,我想避免它.(我不想关闭那个警告,因为当这种比较实际上是无意的时候它是有用的,而忽略编译器警告并不是一个好主意.)
我目前的想法是转换i为无符号类型,只检查上限:
bool is_in_interval(my_type i, my_type max) {
assert(max > 0);
return ((size_t) i <= (size_t) max);
}
Run Code Online (Sandbox Code Playgroud)
如果带符号的类型具有二进制补码表示,则任何负值应该大于max一次强制转换为无符号版本,对吧?如果是这样,这应该工作.但是,我不确定这是否是一种可行的方法.例如,假设签名类型在所有平台上使用两个补码是安全的吗?有没有更好的方法来做到这一点?
我们有一个值列表(foo.lst):
foo,
bar,
baz,
Run Code Online (Sandbox Code Playgroud)
让我们从中得到一个枚举
enum foo {
#include "foo.lst"
_foo_length
};
Run Code Online (Sandbox Code Playgroud)
让我们使用枚举switch:
int main(void) {
enum foo[_foo_length];
switch(f[0]) {
case foo: return 0;
case bar: return 0;
case baz: return 0;
}
__builtin_unreachable();
}
Run Code Online (Sandbox Code Playgroud)
(这段代码很愚蠢,但只是忽略它)
问题:
随着-Wswitch(包括在内-Wall),GCC和Clang(可能还有其他人)会发出警告:
警告:在switch [-Wswitch]中未处理枚举值'_foo_length'
解决方案:
-Wno-switch隐藏警告.case交换机中任何其他缺失的警告.default: unreachable();案例.#define _foo_length (baz + 1),使其不再是枚举的一部分.理想情况下,应该有一种方法可以将枚举值标记为不可赋值,从而使得在读取可能的值时不会在编译器中产生警告,并且不存在此值,而不需要预处理器宏需要重复修改.
有什么相似的吗?我没有想到的任何其他选择?
isnan(), isinf() 直到 C99 才出现在规范中,无论如何在 C89 中实现这样的功能?
我可以if (d * 0 != 0)用来检查 d 是 NaN 还是 Inf,但我们总是使用选项编译我们的项目,该选项-Werror=float-equal想大喊:error: no == or != on float point value
那么人们如何在 C89 中检查 nan 和 inf 呢?
在我寻求免费警告应用程序时,我已经开始使用-Werror来告诉gcc将所有警告视为错误.
这确实非常有用,因为有时我在大型构建输出中错过了一两个(严重)警告.不幸的是,我的项目使用的sqlite3包含许多警告,如sqlite网站中所述,无法消除(他们不想删除).
我想知道是否有一种方法可以使用一些#pragma我可以放在sqlite3.c文件中告诉gcc停止将警告视为仅对该文件的错误.
我尝试过:
#pragma GCC diagnostic ignored "-Werror"
Run Code Online (Sandbox Code Playgroud)
没有成功我也试图逐个列出导致问题的警告:
#pragma GCC diagnostic ignored "-Wextra"
#pragma GCC diagnostic ignored "-Wfloat-equal"
#pragma GCC diagnostic ignored "-Wundef"
...
Run Code Online (Sandbox Code Playgroud)
...遗憾的是,有些警告无法完全关闭(即初始化会从指针目标类型中丢弃限定符).
有什么想法/建议?
我从事的项目具有以下内容:
enum SomeType {
value_100 = 100,
reserved_101 = 101,
value_102 = 102
};
Run Code Online (Sandbox Code Playgroud)
这些“保留的”标识符的存在并不是要改变的权力。
我想以某种方式装饰它们,类似于
[[maybe_unused]],所以我可以打开-Werror=switch
这是一个巨大的(而且很旧的)代码库,重构不使用开关将是一项艰巨的任务,而不是现在的事。
有什么方法可以选择性地使有关gcc中未处理的枚举值的警告静音?请注意,我仍然不希望对枚举值的警告进行修饰。使用gcc扩展名是可以的。