C 指向常量的指针

C 指向常量的指针,c,pointers,C,Pointers,众所周知,通过引用将参数传递给函数是一种很好的做法(特别是当参数的大小与结构类似时)。为了应用“最小特权”原则,如果该函数不应该更改这些传递的变量的值,那么我们需要将它们的引用作为指向常量的指针传递。 我的问题是,作为指向常量的指针不能阻止函数内的值的更改(您可以考虑附加的代码),那么我们如何防止这种做法? void print(const int *ptr) { printf("%d\n", *ptr); int * p = ptr; *p = 11; } 我不是在讨

众所周知,通过引用将参数传递给函数是一种很好的做法(特别是当参数的大小与结构类似时)。为了应用“最小特权”原则,如果该函数不应该更改这些传递的变量的值,那么我们需要将它们的引用作为指向常量的指针传递。 我的问题是,作为指向常量的指针不能阻止函数内的值的更改(您可以考虑附加的代码),那么我们如何防止这种做法?
void print(const int *ptr) {
    printf("%d\n", *ptr);
    int * p = ptr;
    *p = 11;
}
我不是在讨论我们是否可以通过指针改变常数的值。我知道我们可以。但我的问题是,如何防止这种做法,以执行最低特权原则?否则,如果我们可以像上面的代码所示轻松地处理引用,那么将引用作为指向常量的指针传递有什么用呢?因为“函数总是可以投射指针以去除任何
常量限制”(参见jotik的注释),您无法通过语言来阻止它

剩下的就是把它写在你公司的编码标准中,并明确地将它包含在代码评审中,以发现程序员仍在做这件事的地方

当发现此类用途时,可以调查原因。也许程序员是对的,应该更改函数签名(或引入一个新函数)。

因为“函数总是可以投射指针来去除任何
常量限制”(请参见jotik的注释),您无法通过语言来阻止它

剩下的就是把它写在你公司的编码标准中,并明确地将它包含在代码评审中,以发现程序员仍在做这件事的地方


当发现此类用途时,可以调查原因。也许程序员是对的,应该更改函数签名(或者引入一个新函数)。

由于C是非托管的,所以实际上无法防止本地调用的C函数弄乱它自身之外的东西。即使该语言以某种方式强制执行“const ness”,print()还可以做许多其他事情,如果它如此倾向于这样做的话,这将违反最小特权

相反,C提供了合作实施更安全程序的方法。在这种情况下,print()必须通过将
p
声明为指向
const int
的指针来进行协作

作为一个比较点:从安全性的角度来看,C调用方和C函数在相同的信任边界内。具体地说,它们位于同一进程内(因此在本讨论中排除了跨信任边界的调用,如IPC或RPC)。在给定的信任边界内,所有参与者(几乎)都具有相同的权限集。这里的“特权”指的是外部授予的执行某项行动的权利,而不是自我施加的限制

同一信任边界内的参与者可以“自由”相互干预。若函数A篡改了调用方B,那个么并没有比B自己动手更大的威胁了。B可以做同样的事情,不管是自己做的,还是由A做的。从安全角度看,A和B享有同等的特权


因此,在C调用方/函数的情况下,考虑“最小自允许操作的主体”而不是“最小特权的主体”可能会更有帮助。

由于C是非托管的,所以实际上没有任何方法可以防止本地调用的C函数弄乱自身之外的东西。即使该语言以某种方式强制执行“const ness”,print()还可以做许多其他事情,如果它如此倾向于这样做的话,这将违反最小特权

相反,C提供了合作实施更安全程序的方法。在这种情况下,print()必须通过将
p
声明为指向
const int
的指针来进行协作

作为一个比较点:从安全性的角度来看,C调用方和C函数在相同的信任边界内。具体地说,它们位于同一进程内(因此在本讨论中排除了跨信任边界的调用,如IPC或RPC)。在给定的信任边界内,所有参与者(几乎)都具有相同的权限集。这里的“特权”指的是外部授予的执行某项行动的权利,而不是自我施加的限制

同一信任边界内的参与者可以“自由”相互干预。若函数A篡改了调用方B,那个么并没有比B自己动手更大的威胁了。B可以做同样的事情,不管是自己做的,还是由A做的。从安全角度看,A和B享有同等的特权


因此,在C调用方/函数的情况下,考虑“最小自允许操作的主体”而不是“最小特权的主体”可能更有帮助。

此代码
int*p=ptr格式不正确,它不是有效的C

根据简单赋值规则(6.5.16.1),强调:

以下其中一项应适用:

/--/

  • 左操作数具有原子、限定或非限定的指针类型,并且(考虑到左操作数在左值之后的类型) 转换)两个操作数都是合格或不合格的指针 兼容类型的版本,和左侧指向的类型 右侧所指类型的所有限定符

限定符表示类型限定符,例如
const
volatile
。代码中的左操作数与右操作数没有相同的限定符,因此它不应编译。

此代码
int*p=ptr格式不正确,它不是有效的C

根据简单赋值规则(6.5.16.1),强调:

以下其中一项应适用:

/--/

  • 左操作数具有atomi