是否使用未初始化的变量UB的地址?(复制)

时间:2021-04-23 16:50:42

This question already has an answer here:

这个问题已经有了答案:

Is this small code UB?

这个小代码是UB吗?

void Test()
{
  int bar;
  printf("%p", &bar);  
}

IMO it's not UB, but I'd like some other opinions.

我不是UB,但是我想听听其他的意见。

It simply prints the address of bar, even if bar has never been initialized.

它只是打印bar的地址,即使bar从来没有初始化过。

3 个解决方案

#1


7  

TL:DR No, your code does not invoke UB by using anything uninitialized, as you might have thought.

TL:不,您的代码不会像您想的那样使用任何未初始化的东西来调用UB。


The address of a(ny) variable (automatic, in this case) has a defined value, so irrespective of whether the variable itself is initialized or not, the address of the variable is a defined value. You can make use of that value. ( if you're not dealing with pointers and doing double-dereference. :) )

(ny)变量的地址(在本例中为automatic)具有一个定义值,因此无论变量本身是否初始化,变量的地址都是一个定义值。你可以利用这个值。(如果你不是在处理指针和做双删除引用。:))

That said, strictly speaking, you should write

严格地说,你应该写下来

 printf("%p", (void *)&bar);

as %p expects an argument of type pointer to void and printf() being a variadic function, no promotion (conversion) is performed. Otherwise, this is a well-defined behavior.

由于%p期望一个指向void的类型指针的参数和printf()是一个可变函数,因此不会执行任何提升(转换)。否则,这是一个定义良好的行为。

C11, chapter §7.21.6.1

C11、章节§7.21.6.1

p The argument shall be a pointer to void. [.....]

参数应该是指向void的指针。(.....)

#2


4  

Is this small code UB?

这个小代码是UB吗?

Yes, it's UB because the conversion specifier p requires a void-pointer.

是的,它是UB,因为转换说明符p需要一个void指针。

On the other hand the code below does not invoke UB

另一方面,下面的代码不调用UB

void Test(void)
{
  int bar;
  printf("%p", (void*) &bar);  
}

as the address of bar is well defined independently whether bar itself got initialised.

由于bar的地址是独立定义的,不管bar本身是否被初始化。

#3


2  

This behavior is well defined.

这种行为是很明确的。

The address of the variable is known. The fact that it hasn't been explicitly initialized doesn't matter.

变量的地址是已知的。它没有显式地初始化并不重要。

#1


7  

TL:DR No, your code does not invoke UB by using anything uninitialized, as you might have thought.

TL:不,您的代码不会像您想的那样使用任何未初始化的东西来调用UB。


The address of a(ny) variable (automatic, in this case) has a defined value, so irrespective of whether the variable itself is initialized or not, the address of the variable is a defined value. You can make use of that value. ( if you're not dealing with pointers and doing double-dereference. :) )

(ny)变量的地址(在本例中为automatic)具有一个定义值,因此无论变量本身是否初始化,变量的地址都是一个定义值。你可以利用这个值。(如果你不是在处理指针和做双删除引用。:))

That said, strictly speaking, you should write

严格地说,你应该写下来

 printf("%p", (void *)&bar);

as %p expects an argument of type pointer to void and printf() being a variadic function, no promotion (conversion) is performed. Otherwise, this is a well-defined behavior.

由于%p期望一个指向void的类型指针的参数和printf()是一个可变函数,因此不会执行任何提升(转换)。否则,这是一个定义良好的行为。

C11, chapter §7.21.6.1

C11、章节§7.21.6.1

p The argument shall be a pointer to void. [.....]

参数应该是指向void的指针。(.....)

#2


4  

Is this small code UB?

这个小代码是UB吗?

Yes, it's UB because the conversion specifier p requires a void-pointer.

是的,它是UB,因为转换说明符p需要一个void指针。

On the other hand the code below does not invoke UB

另一方面,下面的代码不调用UB

void Test(void)
{
  int bar;
  printf("%p", (void*) &bar);  
}

as the address of bar is well defined independently whether bar itself got initialised.

由于bar的地址是独立定义的,不管bar本身是否被初始化。

#3


2  

This behavior is well defined.

这种行为是很明确的。

The address of the variable is known. The fact that it hasn't been explicitly initialized doesn't matter.

变量的地址是已知的。它没有显式地初始化并不重要。