在其声明的同一语句中使用指针

Using a pointer in the same statement of its declaration

本文关键字:指针 语句 声明      更新时间:2023-10-16

我遇到了一些代码,其中指针在其声明的同一行上使用。这是它的基本SSCCE:

#include "stdafx.h"
#include <iostream>
struct C 
{
    uint32_t a;
};
int main() {
    C* pC = (C*) malloc(sizeof(*pC));     // <---- ???
    pC->a = 42;
    std::cout << pC << std::endl;
    std::cout << pC->a << std::endl;
    free(pC);
}

当我尝试用uint32做类似的事情时(在free()之前插入(:

uint32_t a = a + pC->a;
std::cout << a << std::endl;
然后,要么

不为此语句打印任何内容,要么在调试时将随机值存储在a中,VS2015 会给我一个运行时警告。执行后的错误级别为 3。我知道这是行不通的。

为什么我可以使用指针?它甚至合法吗?为什么编译器不抱怨这样的语句?声明是否在幕后拆分为多个语句?

uint32_t a = a + pC->a;会给你不好的结果,因为你在初始化之前使用了a的值,这是未定义的行为。 有关此内容的更多信息,请参阅为什么"int i = i;"合法?

另一方面,C* pC = (C*) malloc(sizeof(*pC));在初始化中不使用 pC 的值sizeof ,当应用于命名变量时,会为您提供其类型的大小。 这是一个未计算的操作数,这意味着它不会被计算。 所以我们没有使用 *pC 的值,而是我们得到指针指向的大小,C .

您希望这样做的一个原因是,如果您更改了pC类型,则不必更改sizeof部件。 如果你有

C* pC = (C*) malloc(sizeof(C));

然后,您需要记住在更改sizeof(C) pC类型时更改零件。


当然,所有这些都可以通过像这样的std::unique_ptr来避免。

auto pC = std::make_unique<C>();
                           ^ here is the only place you have to specify the type