如何使海湾合作委员会警告传递错误的枚举函数

的gcc似乎没有产生用下面的代码的警告。 我怎样才能得到它产生的警告?

typedef enum { REG8_A, REG8_B, REG8_C }REG8; typedef enum { REG16_A, REG16_B, REG16_C }REG16; void function(REG8 reg8) { } int main(void) { function(REG16_A); // Should warn about wrong enum }

--------------解决方案-------------

这种行为的原因是,您使用的是C编译器,而不是C ++。 而用C枚举类型不是真正的类型,在C枚举牵住INT常数,它们可以与任何整数和任何算术自由混合。

在C ++中,而不是你有真正的枚举,你会这样想他们,并通过语言标准作为传达发生所需要的类型检查。

您的问题可以用两种方法来解决:

  • 使用C ++编译器。

    这样,您将真正的枚举 ,如您所愿。

  • 改变你的代码是纯-C的风格,即不使用枚举,在C它们仅仅是恒定的集合,其中编译器不仅有助于您订购常量值。 而用C,你会成为一个负责,以保持通过常量的“类型”是一致的。 再次声明:对于C,枚举成员只是诠释的常数,你不能让他们打出来。

#define REG8_A 0
#define REG8_B 1
#define REG8_C 2

#define REG16_A 0
#define REG16_B 1
#define REG16_C 2

我可以看到生成的警告的唯一方法是,如果你是准备传递指针,而不是裸露的枚举,如

typedef enum
{
REG8_A,
REG8_B,
REG8_C
} REG8;

typedef enum
{
REG16_A,
REG16_B,
REG16_C
} REG16;

void function(REG8 * reg8)
{

}

int main(void)
{
REG16 r = REG16_A;
function(&r);
return 0;
}

不完全是一个完美的解决方案,但它确实给予警告,至少在gcc -Wall

$ gcc -Wall warn_enum.c -o warn_enum
warn_enum.c: In function 'main':
warn_enum.c:23: warning: passing argument 1 of 'function' from incompatible pointer type
$

对于使用GCC的做到这一点在C方式-Wenum-compare (这是默认如果启用启用-Wall ),则必须将它传递给函数,以获得所需的诊断之前执行的枚举常量的比较。

-Wenum - 比较

警告不同枚举类型的值之间的比较。 在C ++在条件表达式枚举不匹配也被确诊,并警告默认情况下启用。 在C这个警告是被-Wall启用。

http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html

对于这样的比较发生自动发生,当我们调用函数,我们可以在一个宏包的功能。 为了提高可读性我也定义了执行的枚举常量无害的比较(这是试图通过错误的枚举常量时什么最终触发警告宏SAFE_ENUM foobar )。

/**
SAFE_ENUM: evaluate an enumeration constant safely
TYPE: the enumeration type
VAL: the enumeration constant to evaluate
*/
#define SAFE_ENUM(TYPE, VAL) ((VAL) == (TYPE)0 ? (VAL) : (VAL))

typedef enum
{
REG8_DEFAULT,
REG8_A,
REG8_B,
REG8_C
} Reg8;

typedef enum
{
REG16_DEFAULT,
REG16_A,
REG16_B,
REG16_C
} Reg16;

void foo(Reg8 reg8)
#define foo(reg8) foo(SAFE_ENUM(Reg8, reg8))
{
printf("%s called with value %d\n", __func__, reg8);
}

void bar(Reg16 reg16)
#define bar(reg16) bar(SAFE_ENUM(Reg16, reg16))
{
printf("%s called with value %d\n", __func__, reg16);
}

int main(void)
{
foo(REG8_A); // ok
bar(REG16_A); // ok
foo(REG16_B); // warning
bar(REG8_B); // warning

Reg16 a_reg16 = 42;
foo(a_reg16); // warning: foo requires a Reg8 but you gave it a Reg16
}

正如其他人所指出的那样,C不枚举类型和底层整数类型进行区分。 (一些编译器可能包括的类型检查的enum s或typedef能够像扩展;因人而异)

要获得的C类型检查,你可以使用struct S,但你失去了使用的内置比较运算符和能力的switch上的变量。 你可以尝试这样的事情,虽然:

typedef struct {
enum {
reg8_val_A,
reg8_val_B,
reg8_val_C,
} val;
} reg8;
#define reg8_A (reg8){.val = reg8_val_A}
#define reg8_B (reg8){.val = reg8_val_B}
#define reg8_C (reg8){.val = reg8_val_C}

bool
is_A_or_B(reg8 reg) {
if reg.val == reg8_A.val // one way to compare
return true;
switch (reg.val) {
case reg8_val_B: // the other way to compare; note that
return true; // “case reg8_B.val:” will *not* work
case reg8_val_C:
return false;
default:
fprintf(stderr, "bad reg value %d\n", reg.val);
abort();
}
}

(使用了一些C99的功能。)

$ g++ test3.cpp -o test3
test3.cpp: In function 'int main()':
test3.cpp:22: error: cannot convert 'REG16' to 'REG8' for argument '1' to 'void function(REG8)'

随着GCC 4.6,你应该使用-Wconversion-Werror选项,以防止任何隐式类型转换。 它通过代码中的错误张贴由保罗·R.但是原来的代码编译罚款反正。 我不知道为什么。

分类:GCC 时间:2012-01-01 人气:1
本文关键词: 枚举,海合会,GCC警告
分享到:

相关文章

  • 禁用不兼容的选项GCC警告 2012-03-13

    我很好奇,如果有一个选项来禁用有关参数不是有效的被编译的语言gcc的警告. 例如: cc1: warning: command line option "-Wno-deprecated" is valid for C++/Java/ObjC++ but not for C 我们构建系统通过我们决定在全球范围内跨版本的警告. 我们有C / C ++代码,并试图找到实际的警告时警告得到真正讨厌. 有什么建议么? --------------解决方案------------- 在我看来,如果

  • 如何打开GCC警告一个被遗忘的return语句? 2013-10-19

    我怎么打开GCC警告一个被遗忘的return语句? 它应该警告我像下面的情况: int foo() { std::cout << "haha"; } 我知道-Wall打开了警告,但它使太多其他的警告. --------------解决方案------------- 根据GCC的在线文档, -Wall开启: -Waddress -Warray-bounds (only with -O2) -Wc++0x-compat -Wchar-subscripts -Wenum-comp

  • 我怎么能告诉交换机/ case语句GCC警告(或失败)不休息? 2014-01-06

    我有一个复杂的switch语句,我忘了把一个break在一月底case秒. 这是相当法律,并因此我有一个下通到下case . 有什么办法让GCC警告(甚至更好,失败),如果我忽略了把一个break声明? 我认识到,有许多有效的用例(我在我的代码往往使用它们),因为在这个问题上的例子,所以很明显这样的警告(或失败)将需要一个简单的放弃,这样我可以轻松地说,"我做的欲坠,经过这里." 有没有办法告诉GCC来做到这一点? --------------解决方案------------- 有一个

  • 有没有比较两个不同的枚举时避免警告,正确的方法是什么? 2012-09-06

    当比较枚举了来自不同的来源,例如那些以下代码的GCC发出警告. 有没有一种方法,以避免这些警告没有C风格的类型转换? struct Enumerator { enum { VALUE = 5 }; }; template<int V> struct TemplatedEnumerator { enum { VALUE = V }; }; if(Enumerator::VALUE == TemplatedEnumerator<5>::VALUE) { ... } 而海湾合作委员会发出

  • 如何使用Py_BEGIN_ALLOW_THREADS时,为了避免在Python C扩展GCC警告 2014-11-04

    操纵在Python C扩展的GIL最简单的方法就是使用提供的宏: my_awesome_C_function() { blah; Py_BEGIN_ALLOW_THREADS // do stuff that doesn't need the GIL if (should_i_call_back) { Py_BLOCK_THREADS // do stuff that needs the GIL Py_UNBLOCK_THREADS } Py_END_ALLOW_THREADS return b

  • 只有当没有错误的gcc警告 2012-02-15

    是否可以告诉GCC来显示所有的警告(就像-Wall),但仅当有没有错误? 如果有错误 - 只显示他们. --------------解决方案------------- 我不认为如此. 直到它处理完编译单元,这听起来不是很有用的,要求GCC以"缓存"所有的警告. 还有像colorgcc实用程序,使它GCC更明显一点的输出色彩终端 - 也许你会发现有用吗? 你可以把所有的警告与错误-Werror ,从而消除这个问题,但是这不是你后:-)

  • 如何解决以下GCC警告? 2012-09-08

    我已经开始学习OpenGL和管理,以创建一个使用顶点缓冲对象一个旋转的立方体. 然而,当我编译我的代码,GCC发出以下警告: || sdlogl.c: In function ‘initGL’: sdlogl.c|48| warning: implicit declaration of function ‘glGenBuffers’ sdlogl.c|50| warning: implicit declaration of function ‘glBindBuffer’

  • 语义问题GCC警告标志 2013-06-14

    我想沉默语义问题的警告,但我不知道这种类型的警告标志. 你知道国旗的名字吗? 即: 海湾合作委员会的#pragma忽略诊断"-Wsequence点" --------------解决方案------------- #pragma GCC diagnostic只能通过显示的选项使用-fdiagnostics-show-option 与编译-fdiagnostics-show-option ,看看是否有一些[-Wfoo]在警告消息的结尾.

  • 到另一个指针类型为void *的隐式转换GCC警告 2013-10-13

    正如标题所说,是有办法,迫使海湾合作委员会警告我,当我做这样的事情: void do_something(int* ptr) { // do something } int main() { int a = 123; void* b = &a; // WARN HERE: do_something(b); } --------------解决方案------------- 使用-Wc++-compat . 从GCC手册: -Wc ++ - compat的(C和唯一的目标-C) 警告ISO C构造

  • 不明原因的gcc警告:赋值使指针从整数,未投 2014-03-06

    这应该被编译成功课静态库. 当我使用命令:"GCC -c innoprompt.c inprompt.c"我收到了警告,它指向行"尾翼= openFilePrompt();" 从innoprompt.c. 我看不出这会导致怎样此警告. 此外,当我再与该库链接编译实际程序,我得到同样的警告. 由于任务的性质,我不能更改正在调用从库中的函数文件. 这是我的文件头. #pragma once #ifndef LIBINFILEUTIL_H #define LIBINFIL

Copyright (C) 55228885.com, All Rights Reserved.

55228885 版权所有 京ICP备15002868号

processed in 0.740 (s). 10 q(s)