Re: Question about declaring an array in the stack on runtime

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Sat, Jul 15, 2023 at 6:49 PM John Scott <jscott@xxxxxxxxxx> wrote:
> It's not the assignment that's the problem. The problem is that you're
> using a compound literal, and a compound literal, like typical
> automatically allocated variables, has a lifetime determined by its
> scope.
>
> In other words, the following:
> if (some_var == 7) {
> arr = (unsigned int[7]){9, 10, 11, 12, 13, 14, 15};
> }
>
> is the same as
> if (some_var == 7) {
> unsigned int baz[7] = {9, 10, 11, 12, 13, 14, 15};
> arr = baz;
> }
>
> I hope this makes the problem a little more obvious: after you leave the
> '}', the array doesn't exist anymore, and arr is a dangling pointer to
> an object that doesn't exist.

Ah thank you for this John, the rearranged code is particularly illuminating.

On Sat, Jul 15, 2023 at 7:19 PM Xi Ruoyao <xry111@xxxxxxxxxxx> wrote:
> No.  But the usage of arr[i] in the printf call is considered undefined
> behavior.

Got it.

> From C23 6.5.2.5p5:
>
> A compound literal provides an unnamed object whose value, type, storage
> duration and other properties are as if given by the definition syntax
> in the constraints; if the storage duration is automatic, the lifetime
> of the instance of the unnamed object is the current execution of the
> enclosing block.
>
> And 6.2.4p2:
>
> If an object is referred to outside of its lifetime, the behavior is
> undefined.
>
> And 6.8p1:
>
> primary-block:
>   compound-statement
>   selection-statement
>   iteration-statement
>
> And 6.8p3:
>
> A block is either a primary block, a secondary block, or the block
> associated with a function definition;
>
> So here the "enclosing block" is the if statement, after the if
> statement the lifetime of the unnamed object provided by the compound
> literal has ended, thus referring it in the printf call is undefined.

Understood, thank you for the references to the specific clauses. Will
personally study these notes on the lifetimes of compound literals
more for my understanding.

> It's very difficult.  The emit of the warning depends on the optimizing
> of the loop.  Without optimization the compiler doesn't even know the
> loop will be iterated at least once, so there will be no warning is
> produced at -O0.

Ah alright, understood.

> It seems Clang completely unroll the loop and produced a series of
> printf calls at -O2:
>
>         leaq    .str.1(%rip), %rbx
>         movq    %rbx, %rdi
>         movl    $9, %esi
>         xorl    %eax, %eax
>         callq   printf@PLT
>         movq    %rbx, %rdi
>         movl    $10, %esi
>         xorl    %eax, %eax
>         callq   printf@PLT
>
> ... ...

Yes, I noticed that. I would assume that this is more of an artifact
of me hardcoding the value of `some_var`. If the value of `some_var`
cannot be determined at compile time, then I would assume that Clang
would not be able to unroll the loop and all bets are off, especially
since it is UB.

> So obviously -fsanitize=address won't work because there is no memory
> access at all.  On the contrary, clang -fsanitize=address -O0 is able to
> detect the issue.

Oh, interesting. Attempting to specify `-fsanitize=address` on Godbolt
for Clang `-O0` does not seem to detect the issue. I have not tried it
locally though.

> And this is just completely out of the capability of -
> fsanitize=undefined.  Despite the naming, -fsanitize=undefined can only
> catch a *small* subset of undefined behaviors.
>
> Generally sanitizers are useful tools, but not silver bullets.

Noted the part on `-fsanitize=undefined`. Yes, of course, I understand
that sanitizers would not be able to catch all issues.

> I believe there has been a lot of duplicates about "no warnings at -O0".
> And as I've said, these are very difficult to fix.  A lot of warnings
> just inherently needs some information from the optimizer, or there will
> be either too many false positives, or too many false negatives.  If you
> need such warnings, you should enable the optimization.

Understood, no worries. I was just checking on this specific issue.

Thank you for your responses, Xi and John. I hope that both of you
have a great day ahead.

Best regards,
James Raphael Tiovalen




[Index of Archives]     [Linux C Programming]     [Linux Kernel]     [eCos]     [Fedora Development]     [Fedora Announce]     [Autoconf]     [The DWARVES Debugging Tools]     [Yosemite Campsites]     [Yosemite News]     [Linux GCC]

  Powered by Linux