所以我的问题是这样的。如果在头文件中我有一个函数声明:指定指针仅限于声明中吗?
extern void func(void* restrict, void* restrict);
,然后在源文件中,我把它定义为这样的:
void func(void*, void*) {}
这是一个问题? restrict
限定符是否丢失?
P.S.这样我就可以在C89模式下编译源文件,并使用条件宏将标题中的原型更改为相应的C89/C99版本。
所以我的问题是这样的。如果在头文件中我有一个函数声明:指定指针仅限于声明中吗?
extern void func(void* restrict, void* restrict);
,然后在源文件中,我把它定义为这样的:
void func(void*, void*) {}
这是一个问题? restrict
限定符是否丢失?
P.S.这样我就可以在C89模式下编译源文件,并使用条件宏将标题中的原型更改为相应的C89/C99版本。
“这是这样我就可以编译C89模式源文件” - 原因很简单:restrict
不是保留关键字,直到C99 see forword of C11(C99是第2版),所以它只是作为一个名称,这在原型中被忽略了。
但是这两个函数声明器(原型和定义)都必须指定相同的类型,即两个都需要restrict
。
您必须使用正确的C版本编译头文件和实现。对于restrict
,定义通常比原型更相关,但编译器可能能够检测到调用者中的违规。总是假设依靠这样的黑客破坏你的代码。
一个意见后,尝试了一下clairvoyancy的:
如果你想使代码编译古C90,但采取的新功能的优势在哪里有用,您可以使用宏:
#if this_is_c99_or_c11
#define RESTRICT retrict
#else
#define RESTRICT
#endif
void f(int * RESTRICT p);
...
void f(int * RESTRICT p)
{
...
}
还记得可能存在跨版本编译调用者和被调用者的问题。检查你的目标的ABI。
如果你有一个条件宏,为什么你甚至试图使一个定义涵盖两种情况?处理这种情况的“正确”方式是提供两个声明,由宏观警卫分裂,或者将隐藏有问题的关键字置于宏标识符下,而宏标识符本身由警卫给出不同的定义。 – Leushenko