我正在对为不同平台编写的代码进行模块测试,并且遇到需要限制被测模块中数据类型大小的问题。由于我无法直接修改模块文件,我想到使用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’
还有另一种方法可以做这种类型的替换吗?
答案 0 :(得分:3)
为什么你的特定例子失败了,因为它正在扩展到:
unsigned int16_t uii = 3;
unsigned
修饰符显然不适用于int16_t
。
现在回答这个问题:除非编译器有内部选项来更改int
的大小,否则我认为你不能这样做。试图强制它将与内部库函数冲突。
例如:您的printf()
也会中断,因为%d
期望正常int
,但您传递的是16位整数。
编辑:此printf()
示例不是一个好例子,因为int16_t
将被提升为int
。但总体思路仍然存在。 (见评论)
答案 1 :(得分:1)
signed
,unsigned
,long
,short
修饰符只能应用于表示内置类型的关键字。它们不能应用于恰好是内置类型的别名的typename:C语法不允许它。
至于你可以做什么,我认为Mysticial的答案涵盖了它。更改int
的大小将与编译器用于进行库和系统调用的任何ABI冲突,因此如果没有编译器支持,您无法真正执行此操作。例如,假设您有一个声明如下的函数:
int foo(int a);
如果在调用该函数的TU中替换int
的所有提及short
,而不是实现它的TU,那么调用者将通过并接收short
,而函数实现期望并返回int
。这不一定有效。您需要编译所有库,包括标准库和它们所做的任何系统调用,以便调用者和被调用者同意int
的内容。
当然,一种选择是更改您正在测试的所有代码,使用宏代替int
,unsigned int
等。然后标题中的任何函数声明都保持不变。当类型不匹配时会有隐式转换,这可能会引发编译器警告和截断值,但至少已经定义了行为。基本上它是通过预处理器的依赖注入。
答案 2 :(得分:0)
关键是使用
#define int short
代替。