具有指向非常量指针和指向相同地址的常量参数的指针的函数调用

问题描述 投票:3回答:2

我想编写一个输入数据数组并使用指针输出另一个数据数组的函数。

我想知道srcdst都指向同一个地址会导致什么结果,因为我知道编译器可以针对const进行优化。它是未定义的行为吗? (我标记了C和C ++,因为我不确定答案是否可能会有所不同,并且我想了解两者。)

void f(const char *src, char *dst) {
    dst[2] = src[0];
    dst[1] = src[1];
    dst[0] = src[2];
}

int main() {
    char s[] = "123";
    f(s,s);
    printf("%s\n", s);
    return 0;
}

除了上面的问题,如果我删除原始代码中的const,这是否定义明确?

c++ c const undefined-behavior
2个回答
1
投票

具有和不具有const限定符的定义良好。

首先要寻找的是严格的别名规则1。如果srcdst指向同一对象,则它们必须具有compatible types;否则,它们必须具有char*char const*const兼容。

关于dst == src限定词,您可能会争辩说,由于当src您的函数有效地修改了src指向的内容时,const不应该被视为const。这不是const的工作方式。需要考虑两种情况:

  1. [当一个对象被定义为char const data[42];时,如const中一样,对其进行修改将导致未定义的行为。
  2. [如char const* pdata = data;中那样定义了对const对象的引用或指针,只要未定义为int main() { int result = 42; int const& presult = result; const_cast<int&>(presult) = 0; return presult; // 0 } 2(请参见1。),on就可以修改基础对象。因此,以下是明确定义的:
What is the strict aliasing rule?

1)Is const_cast safe?2) const_cast


0
投票

使您的生活更简单,并使用std::array。无论如何,这是因为s本身不是静态的,并且在参数中使用const意味着“我不会更改此[[在函数体中]”,而不是它必须是const本身。


0
投票
虽然行为的定义是正确的,但是-[正确的是编译器可以按照您的意思“优化const”。

也就是说,编译器不能

假定仅由于参数是const T* ptrptr指向的内存就不会通过另一个指针更改。指针甚至不必相等。 const是一种义务,而不是保证-您(=该函数)有义务不通过该指针进行更改。

为了真正获得保证,您需要使用restrict关键字标记指针。这是C99的关键字,不幸的是,到目前为止,它还没有引入C ++。但是,许多编译器都支持__restrict

查看此帖子:

Realistic usage of the C99 'restrict' keyword?

关于restrict关键字的使用方式。

© www.soinside.com 2019 - 2024. All rights reserved.