2016-10-04 33 views
1

所以我的问题是这样的。如果在头文件中我有一个函数声明:指定指针仅限于声明中吗?

extern void func(void* restrict, void* restrict); 

,然后在源文件中,我把它定义为这样的:

void func(void*, void*) {} 

这是一个问题? restrict限定符是否丢失?

P.S.这样我就可以在C89模式下编译源文件,并使用条件宏将标题中的原型更改为相应的C89/C99版本。

+1

如果你有一个条件宏,为什么你甚至试图使一个定义涵盖两种情况?处理这种情况的“正确”方式是提供两个声明,由宏观警卫分裂,或者将隐藏有问题的关键字置于宏标识符下,而宏标识符本身由警卫给出不同的定义。 – Leushenko

回答

2

“这是这样我就可以编译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。

+0

它将被用作一个名字,它会被忽略,但它也会因为'参数重定义'而被编译失败。 – DeiDei

+0

你的意思是它会失败吗?请阅读我的第一段最后一句。在定义的声明器中不允许使用“void *”。 – Olaf

+0

声明一个函数为'void f(void * restrict,void * restrict);'在C89模式下无法在我的'clang-3.9'中进行编译,我引用错误:重新定义参数'restrict'。否则你的回答告诉我在练习中我已经做了什么,所以我会标记为正确的。 – DeiDei