C 是否仅在声明中将指针指定为限制?
所以我的问题是。如果在头文件中我有一个函数声明:C 是否仅在声明中将指针指定为限制?,c,c99,restrict,C,C99,Restrict,所以我的问题是。如果在头文件中我有一个函数声明: extern void func(void* restrict, void* restrict); 然后在源文件中,我将其定义为: void func(void*, void*) {} 这是个问题吗?restrict限定符是否丢失 p.S.这样我就可以在C89模式下编译源文件,并使用条件宏将标题中的原型更改为相应的C89/C99版本。“这样我就可以在C89模式下编译源文件”-原因很简单:restrict在C99之前不是保留关键字(C99是第二
extern void func(void* restrict, void* restrict);
然后在源文件中,我将其定义为:
void func(void*, void*) {}
这是个问题吗?restrict
限定符是否丢失
p.S.这样我就可以在C89模式下编译源文件,并使用条件宏将标题中的原型更改为相应的C89/C99版本。“这样我就可以在C89模式下编译源文件”-原因很简单:restrict
在C99之前不是保留关键字(C99是第二版),所以它只是用作一个名称,在原型中被忽略
但是两个函数声明器(原型和定义)必须指定相同的类型,即两个函数都需要restrict
您必须用正确的C版本编译头和实现。对于restrict
,定义通常比原型更相关,但编译器可能能够检测调用方中的冲突。总是假设依赖这些黑客会破坏你的代码
在评论之后,尝试一点洞察力: 如果您想让代码使用古老的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。它将用作名称,该名称将被忽略,但由于“参数重新定义”,它也将无法编译,您的意思是它将失败吗?请读我第一段的最后一句话<定义的声明符中不允许使用code>void*。将函数声明为
void f(void*restrict,void*restrict)代码>无法在C89模式下以我的clang-3.9
编译,我引用错误:重新定义参数“restrict”
。否则,您的回答告诉了我在实践中已经在做什么,所以我将标记为正确。等等-您想使用restrict
作为参数名吗?不!似乎有一些沟通错误的问题。XD我担心我可能误解了你的第一段,也可能没有。我只是想知道是否可以按照我在问题中描述的那样做。显然不是。如果你有一个条件宏,为什么你要让一个定义同时涵盖这两种情况?处理这种情况的“正确”方法是提供两个声明,由宏保护分割,或者将有问题的关键字隐藏在宏标识符下,保护本身给出了不同的定义。