About Union's question

  • Thread starter =?gb2312?B?zfWzrLey?=
  • Start date
?

=?gb2312?B?zfWzrLey?=

Union un
{ int I;
char c[2];
}

main()
{
union un x;
x.c[0]=10;
x.c[1]=1;
printf("%d",.i);
}


What is the output results? Please explain in detail under.
 
J

jaysome

Union un
{ int I;
char c[2];
}

main()
{
union un x;
x.c[0]=10;
x.c[1]=1;
printf("%d",.i);
}


What is the output results? Please explain in detail under.

That code does not even compile with my compilers and should not
compile with yours. You should at least make an effort to insure that
your code compiles before submitting it to this newsgroup. Otherwise,
it can be difficult for anyone here to provide help to you.

Best regards
 
G

Guest

#include said:
{ int I;
char c[2];
} };

main() int main(void)
{
union un x;
x.c[0]=10;
x.c[1]=1;
printf("%d",.i);

printf("%d\n",x.I);
return 0;> }
Thank you very much!I have something wrong with the procedure, as you
corrected by the right .

#include <stdio.h>
union un
{
int I;
char c[2];
}


int main(void)
{
union un x;
x.c[0]=10;
x.c[1]=1;
printf("%d",.i);

printf("%d\n",x.I);
return 0;
}
Lots of compiler errors and some warnings too, without the modifications
mentioned above. After having fixed these, on one of my machine the output
was 167838688, on another it was 1073807626.
Heavily depends in the implementation and machine architecture (big
endian/little endian)

Bye, Jojo

However, I still do not know how the compiler theory, Why the digital
output ? Depends what the outcome is different for each output?
 
J

Joachim Schmitz

#include said:
Union un union un
{ int I;
char c[2];
} };

main() int main(void)
{
union un x;
x.c[0]=10;
x.c[1]=1;
printf("%d",.i);
printf("%d\n",x.I);
return 0;
}


What is the output results? Please explain in detail under.
Lots of compiler errors and some warnings too, without the modifications
mentioned above. After having fixed these, on one of my machine the output
was 167838688, on another it was 1073807626.
Heavily depends in the implementation and machine architecture (big
endian/little endian)

Bye, Jojo
 
R

Richard Heathfield

??? said:
Union un
{ int I;
char c[2];
}

main()
{
union un x;
x.c[0]=10;
x.c[1]=1;
printf("%d",.i);
}


What is the output results?

It would be undefined because you're missing a header, except that it
won't compile because you're missing an x. And when you've added the x,
you still have to change i to I or I to i (either will do), and U to u.

Once you've done all that, the answer is "it depends".

All in all, I wouldn't bother if I were you.
 
J

jaysome

#include said:
{ int I;
char c[2];
} };

main() int main(void)
{
union un x;
x.c[0]=10;
x.c[1]=1;
printf("%d",.i);

printf("%d\n",x.I);
return 0;> }
Thank you very much!I have something wrong with the procedure, as you
corrected by the right .

Your code still does not compile!
#include <stdio.h>
union un
{
int I;
char c[2];
}

Change that to:

};
int main(void)
{
union un x;
x.c[0]=10;
x.c[1]=1;
printf("%d",.i);

That statement won't compile and requires a diagnostic. Just delete
it, since your following statement is correct.
printf("%d\n",x.I);
return 0;
}

I notice that you changed your posted name from "?????" to "???". I
have a feeling that if you change your posted name to simply "?", your
code will compile :)

All kidding aside, I'll tell you this ... in my 15+ years of
programming in C, I have never--not once--legitimately used a union,
because I've never needed to legitimately use one.

I've dealt with unions declared by compilers, which most compilers
inevitably seem to use (and I can live with that), and I've dealt with
fellow programmers who've declared unions (IMHO, unnecessarily). But
I've never found the need to legitimately use unions myself.

My advice to you is to understand unions, but to never use them in
your own code. In your example, I can tell you that you will not get
the results you expect on a lot of implementations, such as those in
which sizeof(int) != 2 (many if not most) and on those in which the
Endianness is Big when yours is Little or vice versa.

Best regards
 
M

Marcin

Union un
{ int I;
char c[2];
}

After "fixing" your code to make it compiled:

- int 4 bytes
- char 1 byte, char[2] - 2 bytes

so, after union is created it is filled with trash. Then you assign a values
but only to "char" components, the other two bytes of "int" component are
still filled with "trash". So final answer is "you will get unspecified
number".
 
J

Joachim Schmitz

Marcin said:
Union un
{ int I;
char c[2];
}

After "fixing" your code to make it compiled:

- int 4 bytes
- char 1 byte, char[2] - 2 bytes

so, after union is created it is filled with trash. Then you assign a
values
but only to "char" components, the other two bytes of "int" component are
still filled with "trash". So final answer is "you will get unspecified
number".
Ah, yes, I missed that these other bytes still may be uninitialized... (on
an implementation with sizeof(int) != 2)

but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);

would still give some implementation/architecture dependant output.

Bye, Jojo
 
R

Richard Heathfield

Marcin said:

After "fixing" [the] code to make it compiled:

- int 4 bytes
- char 1 byte, char[2] - 2 bytes

What makes you think int is 4 bytes? It might be only one byte, or it
might be two bytes, or it might even be ninety-seven bytes.
 
A

Army1987

Richard Heathfield said:
What makes you think int is 4 bytes? It might be only one byte, or it
might be two bytes, or it might even be ninety-seven bytes.

It can't be one byte.
One byte is defined as the size of an unsigned char, i.e. CHAR_BIT bits.
All 2^CHAR_BIT = UCHAR_MAX + 1 possible sequences of CHAR_BIT bits must be
valid unsigned char representations. Also, CHAR_BIT is required to be at
least 8.

An int must be able to represent all possible values of unsigned char, so
INT_MAX >= UCHAR_MAX.
Also, it must be able to represent all negative numbers down to -INT_MAX.
So, it must be able to represent at least 2*UCHAR_MAX - 1 values. To do
that, it must have at least ceil(log2(2*UCHAR_MAX - 1)) = CHAR_BIT + 1 bits.

Since any object must occupy an integer number of bytes, an int must have at
least 2 bytes.
 
R

Richard Heathfield

Army1987 said:
It can't be one byte.

Yes, it can.
One byte is defined as the size of an unsigned char, i.e. CHAR_BIT
bits. All 2^CHAR_BIT = UCHAR_MAX + 1 possible sequences of CHAR_BIT
bits must be valid unsigned char representations. Also, CHAR_BIT is
required to be at least 8.

All true.
An int must be able to represent all possible values of unsigned char,

Chapter and verse, please.
 
A

Army1987

Richard Heathfield said:
Army1987 said:


Yes, it can.


All true.


Chapter and verse, please.

What is the return type of getchar(), which can be any value from 0 to
UCHAR_MAX, or EOF, totalling 2^CHAR_BIT + 1 values?
 
R

Richard Bos

Army1987 said:
It can't be one byte.
One byte is defined as the size of an unsigned char, i.e. CHAR_BIT bits.
All 2^CHAR_BIT = UCHAR_MAX + 1 possible sequences of CHAR_BIT bits must be
valid unsigned char representations. Also, CHAR_BIT is required to be at
least 8.

An int must be able to represent all possible values of unsigned char, so
INT_MAX >= UCHAR_MAX.

Why?

Richard
 
?

=?gb2312?B?zfWzrLey?=

It can't be one byte.
One byte is defined as the size of an unsigned char, i.e. CHAR_BIT bits.
All 2^CHAR_BIT = UCHAR_MAX + 1 possible sequences of CHAR_BIT bits must be
valid unsigned char representations. Also, CHAR_BIT is required to be at
least 8.

An int must be able to represent all possible values of unsigned char, so
INT_MAX >= UCHAR_MAX.
Also, it must be able to represent all negative numbers down to -INT_MAX.
So, it must be able to represent at least 2*UCHAR_MAX - 1 values. To do
that, it must have at least ceil(log2(2*UCHAR_MAX - 1)) = CHAR_BIT + 1 bits.

Since any object must occupy an integer number of bytes, an int must have at
least 2 bytes.

It may seem very difficult and the things
 
R

Richard Heathfield

Army1987 said:
What is the return type of getchar(), which can be any value from 0 to
UCHAR_MAX, or EOF, totalling 2^CHAR_BIT + 1 values?

The return type of getchar is of course int. Note that this int value
represents "an unsigned char converted to an int". So the conversion
rules apply. If ints are one byte in size, then if the value of the
unsigned char cannot be represented by the int, 3.2.1.2 applies:

"When an integer is demoted to a signed integer with smaller size, or an
unsigned integer is converted to its corresponding signed integer, if
the value cannot be represented the result is implementation-defined."

In C99, it's 6.3.1.3 (3), and the situation is slightly different:

"Otherwise, the new type is signed and the value cannot be represented
in it; either the result is implementation-defined or an
implementation-defined signal is raised."

In neither case (C90 or C99) is int required to be larger than one byte.
It must, of course, be at least 16 bits wide.
 
G

Guest

Richard said:
Army1987 said:


The return type of getchar is of course int. Note that this int value
represents "an unsigned char converted to an int".

What the standard actually says is that fgetc (and thus getc and
getchar) /obtains/ the next "character as an unsigned char converted
to an int", and /returns/ "the next character". This could be
interpreted in two different ways, supporting the claims of both of
you.

A question: does the case of UCHAR_MAX > INT_MAX occur in practice on
any implementation that also provides the standard I/O facilities, or
is the possibility only used for freestanding implementations with no
standard I/O?
 
J

Jack Klein

#include said:
Union un union un
{ int I;
char c[2];
} };

main() int main(void)
{
union un x;
x.c[0]=10;
x.c[1]=1;
printf("%d",.i);
printf("%d\n",x.I);
return 0;
}


What is the output results? Please explain in detail under.
Lots of compiler errors and some warnings too, without the modifications
mentioned above. After having fixed these, on one of my machine the output
was 167838688, on another it was 1073807626.

The result is undefined behavior. The specifics of any output, or
whether there is any output at all, is meaningless in terms of the C
langauge.
Heavily depends in the implementation and machine architecture (big
endian/little endian)

Since it is not C, and the C standard places no requirements on the
program due to the undefined behavior, any further discussion is
rubbish.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
J

Jack Klein

Union un
{ int I;
char c[2];
}

After "fixing" your code to make it compiled:

- int 4 bytes
- char 1 byte, char[2] - 2 bytes

so, after union is created it is filled with trash. Then you assign a values
but only to "char" components, the other two bytes of "int" component are
still filled with "trash". So final answer is "you will get unspecified
number".

No, you will get undefined behavior. There is no number there, as far
as C is concerned.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
J

Jack Klein

Marcin said:
Union un
{ int I;
char c[2];
}

After "fixing" your code to make it compiled:

- int 4 bytes
- char 1 byte, char[2] - 2 bytes

so, after union is created it is filled with trash. Then you assign a
values
but only to "char" components, the other two bytes of "int" component are
still filled with "trash". So final answer is "you will get unspecified
number".
Ah, yes, I missed that these other bytes still may be uninitialized... (on
an implementation with sizeof(int) != 2)

but
union un x;
x.I = 0;
x.c[0]=10;
x.c[1]=1;
printf("%d",x.I);

would still give some implementation/architecture dependant output.

No, it gives you undefined behavior. If you don't understand what
undefined behavior is, or why this program invokes it, you are not
qualified to answer questions on this group.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 
J

Jack Klein

It can't be one byte.

You are absolutely wrong. I work with an implementation regularly
where sizeof(int) is 1. CHAR_BIT is 16.

I have worked in the past with two other implementations where
sizeof(int) is 1. One had CHAR_BIT 24, the other CHAR_BIT 32.
One byte is defined as the size of an unsigned char, i.e. CHAR_BIT bits.
All 2^CHAR_BIT = UCHAR_MAX + 1 possible sequences of CHAR_BIT bits must be
valid unsigned char representations. Also, CHAR_BIT is required to be at
least 8.

The above paragraph is absolutely correct.
An int must be able to represent all possible values of unsigned char, so
INT_MAX >= UCHAR_MAX.

The above paragraph, as Richard points out, is quite wrong. Especially
in a free-standing environment, where none of the functions in the
standard library are required. There is no requirement in the
definition of the integer types that INT_MAX must be greater than or
equal to UCHAR_MAX.
Also, it must be able to represent all negative numbers down to -INT_MAX.
So, it must be able to represent at least 2*UCHAR_MAX - 1 values. To do
that, it must have at least ceil(log2(2*UCHAR_MAX - 1)) = CHAR_BIT + 1 bits.

Since any object must occupy an integer number of bytes, an int must have at
least 2 bytes.

Dead wrong, especially in free-standing environments.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://c-faq.com/
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.club.cc.cmu.edu/~ajo/docs/FAQ-acllc.html
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,755
Messages
2,569,535
Members
45,007
Latest member
obedient dusk

Latest Threads

Top