混合typedef和define以强制数据类型大小

时间:2011-10-26 08:31:24

标签: c gcc types

我正在对为不同平台编写的代码进行模块测试,并且遇到需要限制被测模块中数据类型大小的问题。由于我无法直接修改模块文件,我想到使用stdint.h typedef并使用define替换模块声明。在本质上:

#include <stdint.h>
#define int int16_t

int main() {
    uint16_t ui = 2;
    unsigned int uii = 3;
    printf("Hello\n");
    printf("Test %d, %d\n", ui, uii);
    return 0;
}

但是这个消息失败了:

error: expected ‘=’, ‘,’, ‘;’, ‘asm’ or ‘__attribute__’ before ‘uii’

还有另一种方法可以做这种类型的替换吗?

3 个答案:

答案 0 :(得分:3)

为什么你的特定例子失败了,因为它正在扩展到:

unsigned int16_t uii = 3;

unsigned修饰符显然不适用于int16_t

现在回答这个问题:除非编译器有内部选项来更改int的大小,否则我认为你不能这样做。试图强制它将与内部库函数冲突。

例如:您的printf()也会中断,因为%d期望正常int,但您传递的是16位整数。

编辑:此printf()示例不是一个好例子,因为int16_t将被提升为int。但总体思路仍然存在。 (见评论)

答案 1 :(得分:1)

signedunsignedlongshort修饰符只能应用于表示内置类型的关键字。它们不能应用于恰好是内置类型的别名的typename:C语法不允许它。

至于你可以做什么,我认为Mysticial的答案涵盖了它。更改int的大小将与编译器用于进行库和系统调用的任何ABI冲突,因此如果没有编译器支持,您无法真正执行此操作。例如,假设您有一个声明如下的函数:

int foo(int a);

如果在调用该函数的TU中替换int的所有提及short,而不是实现它的TU,那么调用者将通过并接收short,而函数实现期望并返回int。这不一定有效。您需要编译所有库,包括标准库和它们所做的任何系统调用,以便调用者和被调用者同意int的内容。

当然,一种选择是更改您正在测试的所有代码,使用宏代替intunsigned int等。然后标题中的任何函数声明都保持不变。当类型不匹配时会有隐式转换,这可能会引发编译器警告和截断值,但至少已经定义了行为。基本上它是通过预处理器的依赖注入。

答案 2 :(得分:0)

关键是使用

#define int short

代替。