GCC vs Clang replicates a flexible structure element

Consider the following code snippet.

#include <stdio.h>

typedef struct s {
    int _;
    char str[];
} s;
s first = { 0, "abcd" };

int main(int argc, const char **argv) {
    s second = first;
    printf("%s\n%s\n", first.str, second.str);
}

When I compile this with GCC 7.2, I get:

$ gcc-7 -o tmp tmp.c && ./tmp
abcd
abcd

But when I compile this with Clang (Apple LLVM version 8.0.0 (clang-800.0.42.1)), I get the following:

$ clang -o tmp tmp.c && ./tmp
abcd
# Nothing here

Why is the output different from each other? I would expect the string to not be copied, as this is a flexible array element (similar to this question ). Why does GCC actually copy it?

Edit

Some comments and the answer suggest that this may be related to optimization. GCC can make an secondalias first, so the update secondshould prevent GCC from performing this optimization. I added the line:

second._ = 1;

But this does not change the result.

+4
source
2

, gcc. second , . first. , .

, s second = first; , (a) gcc second, (b) first , .

, :

#include <stdio.h>

typedef struct s {
    int _;
    char str[];
} s;
s first = { 0, "abcdefgh" };
int main(int argc, const char **argv) {
    char v[] = "xxxxxxxx";
    s second = first;
    printf("%p %p %p\n", (void *) v, (void *) &first, (void *) &second);
    printf("<%s> <%s> <%s>\n", v, first.str, second.str);
}

32- Linux gcc :

0xbf89a303 0x804a020 0xbf89a2fc
<defgh> <abcdefgh> <abcdefgh>

, v second , first - . , , second v , <xxxxxxxx> <defgh>.

gcc- . , , second , , .

Edit: , second :

s second;
second = first;

- . first, , , . , first , , , v , second.str - undefined. gcc , first .

+2

, , , , - undefined.

GCC
second, GCC second first . , GCC , /, Clang.

Clang
, . , , : int .

, second , . , . , .

- , , .., . , ; , , . , , .


, godbolt.org :

.LC0:
        .string "%s\n%s\n"
main:
        sub     rsp, 24
        mov     eax, DWORD PTR first[rip]
        mov     esi, OFFSET FLAT:first+4
        lea     rdx, [rsp+16]
        mov     edi, OFFSET FLAT:.LC0
        mov     DWORD PTR [rsp+12], eax
        xor     eax, eax
        call    printf
        xor     eax, eax
        add     rsp, 24
        ret
first:
        .long   0
        .string "abcd"

, GCC , OPs: second first.

Tom Karzes , , . , , , ; , , .

-1

Source: https://habr.com/ru/post/1687690/


All Articles