3

我正在尝试编译 -Wall -Werror 及其限制我的风格。

我试图明确指出某些参数是常量,然后将它们传递给大型库中的非 const 限定函数。

PS我这样做主要是为了弄清楚某些变量是常量,在处理不使用const的库函数时这样做是好是坏?

4

3 回答 3

1

如果您将这些常量作为引用参数或通过指针传递给例程,那么这些警告可能有一个很好的理由。你怎么知道这些例程不会修改你的“常量”?你告诉那些变量永远不会改变的代码的其余部分会搞砸什么?

如果你真的确定你正在做的事情是安全的,并且没有很好的方法来重新编码以消除警告,你可以使用 pragmas 在 gcc 中关闭一些警告。对尽可能小的代码区域执行此操作,并说明您这样做的原因。

请勿滥用此特权,否则您可能会被代码警察逮捕并被判处 9 个月的 Ada 社区服务编码。这将治愈你再次抱怨 C 的警告。

于 2011-02-25T11:28:03.943 回答
1

使用-Wno-ignored-qualifiers开关。

有时,在编译时-Wall -Wextra -Werror(我也是这样做的,因为这是非常好的做法),您会面临反复出现的警告,您可能希望在项目范围内或在每个源文件的基础上禁用。例如,我在项目中经常禁用的一个是-Wno-long-long. 这不是坏习惯,因为您知道自己在做什么,并且您不想控制第三方代码。

据我了解,您正在尝试禁用代码特定部分的警告,否则会破坏您在const任何地方的努力。在这种情况下,请执行以下操作:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wignored-qualifiers"

OffendingThirdPartyFunction(MyConstParam);

#pragma GCC diagnostic pop

或者(未经测试,我不知道在哪里放置分号,而且我这里没有工作的 GCC)

#define NO_WARNING(expr)                                        \
    _Pragma("GCC diagnostic push")                              \
    _Pragma("GCC diagnostic ignored \"-Wignored-qualifiers\"")  \
    expr                                                        \
    _Pragma("GCC diagnostic pop")

NO_WARNING(OffendingThirdPartyFunction(MyConstParam));

或者,您可以使用演员表。这是迄今为止最便携的解决方案。

OffendingThirdPartyFunction((param_t*)MyConstParam);
于 2011-02-25T11:36:12.993 回答
0

不要使用命令行选项:警告告诉您您的代码不是 const 安全的。没错,您的代码不是const 安全的,尽管这是编写您正在使用的库的人的错。

如果您禁用警告,那么即使您编写不安全的代码并且这您的错,您也不会再收到警告。

相反,只要库函数之一采用指向非 const 的指针,但保证不修改指针的引用,然后将 const-ness 从您的指针中转换出来,然后传递它。演员表作为代码中的记录,您(程序员)声称不会发生任何无效的事情,即使类型系统无法证明这一点,并且可能应该被注释。

例如:

// in this library
void print_int(int *p) { printf("%d\n", *p); }
void set_int(int *p) { *p = 6; }

// your code
const int n = 5;
print_int((int*)(&n)); // warning suppressed for this call only,
                       // having carefully checked the print_int docs.

// further down your code
set_int(&n); // You *want* the compiler to stop this!

或者,如果您可能会感到困扰(因为您有很多这样的调用),请为有问题的库函数编写包装器:

void print_int_const(const int *p) { print_int((int*)(p)); }
// but no wrapper for set_int

请注意,演员表也会删除volatile(并且通常会接受很多不正确的输入)。重载可以防止您意外使用完全错误的类型,而就地强制转换不会。

于 2011-02-25T13:04:26.263 回答