如果您使用现有的C代码库并使用C++编译器进行编译,那么您可能会遇到什么样的问题?例如,我认为将一个整数分配给具有枚举类型的值将在C++中失败,而在C中它是合法的(如果有点讨厌).
如果我没有包装我的所有C文件extern C { ... }
,我是否会在最不期望的地方获得名称错误?有什么理由我真的不应该这样做吗?
作为背景,我们有一个用C编写的非常大的代码库.几年来,我们一直在跳过箍来做一些自然而然的事情来通过C++(例如homebrewe继承).我们希望开始转向C++,但是要逐步进行; 获得我们类似CORBA的框架来支持它,并在我们继续使用C++提供的更自然的方法时重构模块.
c c++ migration compiler-construction language-interoperability
请参阅下面的简单示例.当一个函数返回一个enum
被分配给一个不同的变量enum
我甚至没有得到任何警告gcc -Wall -pedantic
.为什么C编译器不能对enum
s 进行类型检查?还是gcc
具体的?我现在无法访问任何其他编译器来试用它.
enum fruit {
APPLE,
ORANGE
};
enum color {
RED,
GREEN
};
static inline enum color get_color() {
return RED;
}
int main() {
enum fruit ftype;
ftype = get_color();
}
Run Code Online (Sandbox Code Playgroud) 虽然我知道这是有效的C不能区分枚举类型.
GCC确实-Wenum-compare
(我正在使用)并按预期工作.
我试过使用,-Wconversion
但这没有任何区别.
分配和算术运算符(+
/ -
/ &
/ |
...等)如何产生警告?(作业,或者......等)
{
enum Foo f = SOME_VALUE;
enum Bar b = SOME_OTHER_VALUE;
if (f != b) {
/* this warns! */
}
f = b; /* <-- how to warn about this? */
f |= b; /* .. and this? */
}
Run Code Online (Sandbox Code Playgroud)
笔记:
考虑一个大型项目,其中有许多类型typedef
,例如
typedef int age;
typedef int height;
Run Code Online (Sandbox Code Playgroud)
和一些函数获取这些类型的参数:
void printPerson(age a, height h) {
printf("Age %d, Height %d\n", a, h);
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在编译时警告,如果这些参数是错误的类型,例如
age a = 30;
height h = 180;
printPerson(h, a); /* No warning, because a and h are both integers */
Run Code Online (Sandbox Code Playgroud)
在这种情况下,gcc(或某些静态代码分析工具)是否有选项可以发出警告?
如果我有多个enum
,例如:
enum Greetings{ hello, bye, how };
enum Testing { one, two, three };
Run Code Online (Sandbox Code Playgroud)
如何强制使用正确的enum
?例如,我不希望有人hello
在他们应该使用时使用它们以one
获得更好的调试和可读性.
在C中,或者至少在GCC中,是否有某种方式(使用typedef)是一种与任何其他类型不兼容的类型?
例如,你做:
typedef UINT UID;
typedef UINT AGE;
UID user_id;
AGE user_age;
Run Code Online (Sandbox Code Playgroud)
您可以看到两种类型都是unsigned int(我将其命名为UINT).
您可以计算user_id + user_age.
但是,你想确保UID和AGE永远不会混在一起.
这就是我想要的!
这个想法是为了代码的安全性和正确性,为某些类型指定一些限定符/属性.
然而,混合它们的唯一方法是将两者都转换为UINT,或者将user_age转换为UID.
C语言可能会非常混乱,有时候我们只是因为你使用了错误的值作为参数而只是因为你使用了错误的值作为参数,因为变量具有相似的名称......并且编译器显然永远不会抱怨,因为它们只是为了找出愚蠢的bug.有相同的类型.
我在GCC手册中没有找到任何相关内容,但我会在邮件列表中提出要求.
我只是想知道如何(而且我知道没有,我真正的问题是为什么标准和编译器不提供这个,因为我认为它非常有用并且是相对容易实现的最简单的事情之一在编译器方面)在类型(以及变量)上指定一些ATTRIBUTE,告诉编译器TYPE不应该与任何其他类型混合,除非明确地转换为它.所以真正的问题是: - 为什么这是一个坏主意?(为什么没有编译器考虑它?) - 如果存在这个GCC属性,你还会使用它吗?哦...在我看来我会在这里和那里使用它,只是把这个属性放在几乎所有的typedef然后只是编程; 在第一次编译时会检测到错误的巨大部分 - 以错误的顺序传递参数,在大而复杂的计算中使用错误的变量......
对不起,我的英语不好.
是否有可能对#define宏进行类型检查?例如:
typedef enum
{
REG16_A,
REG16_B,
REG16_C
}REG16;
#define read_16(reg16) read_register_16u(reg16); \
assert(typeof(reg16)==typeof(REG16));
Run Code Online (Sandbox Code Playgroud)
上面的代码似乎不起作用.我究竟做错了什么?
顺便说一下,我正在使用gcc,我可以保证我将永远在这个项目中使用gcc.代码不需要是可移植的.
我从教科书中了解到,枚举的典型定义如下:
enum weather {
sunny,
windy,
cloudy,
rain,
} weather_outside;
Run Code Online (Sandbox Code Playgroud)
然后声明一个 var,如下所示:
enum weather weather_outside = rain;
Run Code Online (Sandbox Code Playgroud)
我的问题是,如果可以通过说eg来使用枚举常量rain
,它保持整数3,那么具有类似类型的更复杂的减速等于3的确切用途和意义是什么enum weather weather_outside = rain;
(weather_outside
因为枚举值只能是编译时常量)?为什么不直接使用 aconst
或 宏呢?我有点困惑枚举是否真的有必要?!