1

I have a strange problem. Here are two source code.

/*---main.c---*/
#include <stdio.h>
int d=100;
int x=200;
void p1(void);
int main() {
    p1();
    printf("d=%d,x=%d\n",d,x);
    return 0;
}
/*---p1.c---*/
double d;
void p1() {
    d=1.0;
}

I compile the code and link. I get a warnning:

/usr/bin/ld: Warning: alignment 4 of symbol `d' in /tmp/ccuZEbnu.o is smaller than 8 in /tmp/ccrTyML7.o

I excute the program and get the result d=0,x=1072693248, why not d=100,x=200 ? This is so strange that I cannot understand. I try to print the address of d and x, I found that the address of variable d in the two source codes are totally same. I think two variable d in different source code should be different because it has no extern.

I'm a newbie. Sorry for my poor English. Thanks for your help in advance.

6
  • 1
    C and C++ are very different languages. Please don't tag both unless your question is specifically about their differences. Commented Sep 1, 2020 at 9:22
  • return is not exist in the function. also you need to define output data type of the function ex) int user_function () { return int type output} Commented Sep 1, 2020 at 9:25
  • 1
    You might want to read what static keyword is used for. Commented Sep 1, 2020 at 9:25
  • @Gerhardh I got it, the variable was extern in default. Commented Sep 1, 2020 at 9:31
  • @guapi, you could post an answer. Commented Sep 1, 2020 at 10:02

2 Answers 2

1

I try to explain this problem after STFW. First, the global variable was extern by default, so the address of two variable are same. What the type of d? I think it should be int. This is related to strong symbols and weak symbols in the linking stage. I try to printf("sizeof(d)=%u\n", sizeof(d)), then I will get the result: sizeof(d)=4. I also print the address of d and x, they differs by 4 bytes. But How to explain the behavior in p1.c? I give my understanding:

void p1()
{
    *(double *)(&d) = 1.0;
}

Because of the address of d and x differs by 4 bytes, and the size of double was 8 bytes, so this code concurrently changed the values of x. If there are some errors, please point out it.

Sign up to request clarification or add additional context in comments.

Comments

0

The program has undefined behavior because the name d with external linkage is defined twice in the same file scope.

So it seems the linker defined only the external variable d declared as having the type double. In this case as the size of the type double is equal to 8 then an object of the type int that has the size equal to 4 occupies one half of the allocated memory that was set to zero due to this assignment

d=1.0;

Here is a demonstrative program that shows how for example an object of the type double having the value 1.0 can be represented internally.

#include <stdio.h>

int main(void) 
{
    double d = 1.0;
    
    for ( char *p = ( char * )&d; p < ( char * )&d + sizeof( double ); ++p )
    {
        char c = *p >> 4 & 0x0f;
        if ( c > 9 ) c = c - 10 + 'A';
        else c += '0';
        putchar( c );
        c = *p & 0x0f;
        if ( c > 9 ) c = c - 10 + 'A';
        else c += '0';
        putchar( c );
    }

    putchar( '\n' );
    
    return 0;
}

The program output is

000000000000F03F

As you can see one part with the length equal to 4 bytes of the internal representation of the double number consists from all zeroes.

This part was selected in the generated object code as an object of the type int.

Now if you will output the value x=1072693248 in hex like this

printf( "%x\n",  1072693248u );

you will get

3ff00000

That is it is the second half of the internal representation of the double number d.

So either rename the variable d in one of the modules or declare it with internal linkage using the storage specifier static.

2 Comments

Shouldn't the linker simply complain about d being multiply defined?
@Jabberwocky Yes, it should. But we do not know whether the message was ignored by the user.:) As a result the program has undefined behavior.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.