【问题标题】:Is it undefined behavior to modify a value that I also have a const pointer pointing to修改一个我也有一个 const 指针指向的值是未定义的行为吗
【发布时间】:2016-06-26 09:37:08
【问题描述】:

以下场景是否有未定义的行为?

void do_stuff(const int *const_pointer, int *pointer) {
    printf("%i\n", *const_pointer);
    *pointer = 1;
}

int data = 0;
do_stuff(&data, &data);

如果这是未定义的行为,如果编译器假定const_pointer 指向的值永远不会改变,则可能会导致问题。在这种情况下,它可能会重新排序do_stuff 中的两条指令,从而将行为从预期的printf("0") 更改为printf("1")

【问题讨论】:

  • 没有。 const 不能这样工作。如果这样做,那将比完全没用更糟糕。指针上的const 意味着无法通过此指针更改对象,而不是根本无法更改。
  • @n.m.有时有一种方法可以告诉编译器“我保证指针指向的数据已经初始化并且不会再被修改”,例如在函数中多次计算相同的表达式时,并且如果表达式的输入确实是常量,编译器可以确保它只计算一次。虽然const 不能以这种方式工作是对的,但我认为如果这样做的话,它不会“比完全没用更糟糕”。
  • @hvd:这就是 C99 中的 restrict 的用途。不完全是这样(这个概念更笼统),但结合const,它也打算产生这种效果。
  • @hvd:是的,这就是我所说的更笼统的概念的意思。 restrict 并不是说​​指向的对象是不可修改的。相反,它有助于编译器确定指针对象(可能是可修改的)是否实际上被一些代码修改。无论是否存在const,它都应该有助于编译器优化代码。我想说它达到了与建议的“硬 const”相同的效果,但以更通用的方式。
  • @hvd 显然是 restrict + const 你可以告诉编译器对象不会被修改:stackoverflow.com/a/28800332/4082723

标签: c pointers constants undefined-behavior


【解决方案1】:

如果编译器可以证明指向 const 的指针指向的值指针不会改变,那么它就不需要重新加载值,或者保持顺序。

在这种情况下,这是无法做到的,因为这两个指针可能有别名,因此编译器不能假定指针不指向同一个对象。 (函数的调用可能来自不同的翻译单元,编译器不知道传递给函数的内容。)

您的示例中没有未定义的行为,您可以保证 printf 将输出 0

【讨论】:

    【解决方案2】:

    const_pointer 仅表示它指向的数据不能更改。

    当你传递一个指向你的函数的指针时,它是否应该是const 完全由你来决定。 const 是一种保护工具,可防止对数据进行不必要的更改。但是没有const,函数仍然可以工作。例如,您自己的版本的strcpy 可以写成:

    strcpy( char *s, const char *t );
    

    或者,

    strcpy( char *s, char *t ); // without const, still work, just not as good as the first version

    因此,您的代码中不应有任何意外:您不能通过const_pointer 修改数据,但可以通过pointer 修改数据(即使两个指针指向同一位置)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-19
      • 2010-10-21
      • 2010-09-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多