2013-04-05 35 views
7
typedef int A; 
typedef int B; 

void foo(A arg){} 

void main(void){ 
    B wrongvar = 7; 
    foo(wrongvar); 
} 

这个结构是否应该按照标准返回一个警告/错误?最受欢迎的编译器呢?使用'typedef'来确保逻辑类型的安全

例如:我们有变量,代表千克和米,都是'int'类型。我们有一个功能,处理仪表。我们希望编译器捕捉错误,这与将千克含义变量变量传递给该函数有关。

我相信Ada处理顺利。现代C呢?

+1

一个'typedef'给出了一个新的名称改为现有类型;它不会创建一个新的类型。替代名称也指相同类型。因此,所有'A','B','int'和'signed int'都可以传递给'foo(A arg)',而不会违反类型(其他类型可以转换为'int',比如'enum'类型,也可以传递而不引发警告)。 – 2013-04-28 17:21:06

+0

'void main(void)'应该是'int main(void)' - 任何引用告诉你使用'void main(void)'是由不熟悉C的人编写的。 – 2016-03-02 21:06:03

+0

@KeithThompson,c99似乎[支持](http://stackoverflow.com/a/9356660/1145760)这种使用'void main(void)'。误解是因为我没有正确地标记问题。 – Vorac 2016-03-07 08:16:12

回答

7

不,您正在处理的是类型问题已知的问题作为结构对等与名称对等。正如狗所说,你可以做的最接近的事情就是使用结构,但如果编译器选择添加填充(在这种情况下不太可能),这可能会浪费内存。 C对别名使用结构等价(意味着两种类型是相同的),但是对于不同的声明结构(具有相同布局的两种结构类型不被视为等同),名称等价。

使用结构要做到这一点的例子:

typedef struct { 
    double value; 
} meters; 

typedef struct { 
    double value; 
} kilograms; 

int main(){ 
    meters m; 
    kilograms k = {2}; // initialized 
    m.value = 1; 
    k = m; // error, can't assign meters to kilos 
    return 0; 
} 

您不妨看看这篇文章:http://www.joelonsoftware.com/articles/Wrong.html描述了如何避免这些问题的命名约定

+2

类型名称的_t后缀由POSIX保留。由于类型与变量存在于独立的命名空间中,因此无论如何都没有理由使用独特的后缀。 http://stackoverflow.com/a/231807/139746 – 2013-04-28 17:16:26

+1

好吧,消除 – 2013-04-28 17:35:13

+0

这只是一个中途解决方案,因为有一天一个新手来写并写'k.value = m.value;'没有更深入地考虑后果。如果你想要有真正的安全性,你必须定义你自己的类(在你的情况可能包装int作为数据成员),并允许运营商。 – 2016-03-02 17:10:46

2

你可以使用一个结构与一个字段来做你想要的。唯一的“缺点”是,如果优化器不优化它们,则可能会浪费1/2/4/8字节...

+3

struct的大小只是其成员变量的大小加上任何填充(如果需要)的总和。如果只有一个成员变量,我认为在空间方面不会有任何开销。 – 2013-04-28 16:34:04