Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/typo3/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 确保返回的指针为常量,而不引发警告_C_Constants_Compiler Warnings_Rvalue_Function Declaration - Fatal编程技术网

C 确保返回的指针为常量,而不引发警告

C 确保返回的指针为常量,而不引发警告,c,constants,compiler-warnings,rvalue,function-declaration,C,Constants,Compiler Warnings,Rvalue,Function Declaration,我的目标是为我的库定义一个干净的API。 我的一个函数返回一个指针,该指针不能用指针算术修改。 为了在编译时做到这一点,我计划在函数原型中使用const关键字 下面是一个天真的例子: int global_var = 12; int* const access_global_var(){ return &global_var;} int main(void) { int* const ptr = access_global_var(); *ptr = 15; //<

我的目标是为我的库定义一个干净的API。
我的一个函数返回一个指针,该指针不能用指针算术修改。
为了在编译时做到这一点,我计划在函数原型中使用
const
关键字

下面是一个天真的例子:

int global_var = 12;

int* const access_global_var(){ return &global_var;}

int main(void) {
  int* const ptr = access_global_var();

  *ptr = 15;  //< Should be valid 
  ptr++;      //< Should be Invalid 
  return 0;
}
这个警告正确吗?有什么我遗漏的吗?有没有更好的方法来实现我的目标?
由于警告在我的项目中被视为错误,正如您所料,这是有问题的。

感谢函数的返回类型

int* const access_global_var(){ return &global_var;}
没有道理

如果您在任何情况下都要删除限定符const,那么您可以不编写

++access_global_var();
因为函数返回一个右值

但即使你有限定符const,你也可以写

int *p = access_global_var();
然后

++p;
也就是说,您可以为非常量对象指定一个常量值


因此,编译器警告说,返回类型中使用的限定符没有意义,可以在不更改逻辑的情况下删除。

如果出于某种原因,您真的想强制开发人员这样做(如果他们愿意,他们将很容易绕过此限制),您始终可以使用类似宏的函数来强制执行此操作。如果希望宏特定于特定的全局变量,如示例中所示,它可能如下所示:

#define create_global_var_accessor(ACCESSOR) \
    int *const ACCESSOR = &global_var

int global_var = 12;

int main(void) {
    create_global_var_accessor(ptr);

    *ptr = 15;  //< Should be valid 
    ptr++;      //< Should be Invalid 
    return 0;
}

除此之外,我将附和莫斯科的Vlad说,我认为这不是一个需要解决的问题。

您不需要限定返回值。您分配返回值的变量是您需要限定的地方。我同意我不需要它。但是有没有一种方法可以强制用户使用const及其变量­?即使您可以强制调用方只将函数值分配给
const
,实际上需要
int*const x=access_global_var(),则调用方可以执行
int*y=x。想象一下,如果函数返回的是一个简单的
int
,而不是指针,您会问什么。坚持调用者只能给
constintx=3分配一个返回值,比如3,有什么用并且永远不允许将自己的
x
用于任何其他用途?他们必须能够在表达式中使用
x
,是吗?说
x+4
?这也不应该是常数,对吗?……假设你可以强制一个常数x=3并以某种方式传播此消息以禁止
inty=x。但是,如果
x+4
也没有被强制为
const
,那么他们可以写入
x+0
来删除
const
,从而执行
int y=x+0。或者,如果你不允许,那么
inty=x+4-4。类似地,指针可以是
int*x=access\u global\u var()+1-1。或者
int*x=access\u global\u var+HardToEvaluateFunction(),这将阻止编译器知道函数返回零。从语言设计的角度来看,这个要求是不可行的。我理解左值。事实上,您可以编写
int*p=access\u global\u var()
是我要解决的问题。@gberth为什么是问题?为什么用户不能增加指针?他不会通过增加指针来更改全局变量。
#define create_global_var_accessor(TYPE, ACCESSOR, ACCESSEE) \
    TYPE *const ACCESSOR = &(ACCESSEE)

int global_var = 12;

int main(void) {
    create_global_var_accessor(int, ptr, global_var);

    *ptr = 15;  //< Should be valid 
    ptr++;      //< Should be Invalid 
    return 0;
}