News:

Download Pelles C here: http://www.smorgasbordet.com/pellesc/

Main Menu

why?

Started by jordantoto, October 24, 2018, 02:27:19 AM

Previous topic - Next topic

jordantoto

Results of three IDEs on one computer.

why???
pelles c        grade =F
codeblocks     grade=E
VS2017         grade=E

code:
#include <stdio.h>

int main(void)
{

   char grade = 'FATE';


   printf("grade = %c\n", grade);

   return 0;
}


TimoVJL

#1
You have problem with that code, c is only one byte in size:
PellesC:
test_grade.c(7): warning #2055: Excess characters in 'char' character literal ignored.
msvc:test_grade.c(7): warning C4305: 'initializing': truncation from 'int' to 'char'

Clang:
test_grade.c(7,17):  warning: implicit conversion from 'int' to 'char' changes
      value from 1178686533 to 69 [-Wconstant-conversion]
   char grade = 'FATE';


1178686533 = 46415445h -> 'F','A','T','E'
May the source be with you

jordantoto

Quote from: TimoVJL on October 24, 2018, 08:33:01 AM
You have problem with that code, c is only one byte in size:
PellesC:
test_grade.c(7): warning #2055: Excess characters in 'char' character literal ignored.
msvc:test_grade.c(7): warning C4305: 'initializing': truncation from 'int' to 'char'

Clang:
test_grade.c(7,17):  warning: implicit conversion from 'int' to 'char' changes
      value from 1178686533 to 69 [-Wconstant-conversion]
   char grade = 'FATE';


1178686533 = 46415445h -> 'F','A','T','E'

Thank you for your answer!
But I still don't understand why the results of the book and pelles c are different.

Forgive me, after all, my English is not good! XD

frankie

#3
Quote from: jordantoto on October 24, 2018, 10:04:04 AM
But I still don't understand why the results of the book and pelles c are different.
First of all IDE is not a compiler (it is an integrated development environment). So I suppose that you are using MingW->codeblocks and MSVC->VS.
Now the behavior of multibyte sequences is "implementation-defined", meaning that it could be implemented in different ways by different compilers.
I.e. in the case of VS and MingW (gcc) it seems that the character constant 'FATE' is first packed in an int in the little endian format with LSbyte holding the 'E'. Then converting the integer constant to char the truncation gives the LSB value, 'E', to print.
PellesC seems to 'optimize' the code using just the first character, 'F'.

For further details check ISO/IEC 9899:2011 §6.4.4.4 Character constants:
Quote
Description:
An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in 'x'.
A wide character constant is the same, except prefixed by the letter L, u, or U.
With a few exceptions detailed later, the elements of the sequence are any members of the source character set; they are mapped in an implementation-defined manner to members of the execution character set.
And
Quote
Constraints:
An integer character constant has type int.
The value of an integer character constant containing a single character that maps to a single-byte execution character is the numerical value of the representation of the mapped character interpreted as an integer.
The value of an integer character constant containing more than one character (e.g. 'ab'), or containing a character or escape sequence that does not map to a single-byte execution character, is implementation-defined.
If an integer character constant contains a single character or escape sequence, its value is the one that results when an object with
type char whose value is that of the single character or escape sequence is converted to type int.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

jordantoto

Quote from: frankie on October 24, 2018, 01:32:12 PM
Quote from: jordantoto on October 24, 2018, 10:04:04 AM
But I still don't understand why the results of the book and pelles c are different.
First of all IDE is not a compiler (it is an integrated development environment). So I suppose that you are using MingW->codeblocks and MSVC->VS.
Now the behavior of multibyte sequences is "implementation-defined", meaning that it could be implemented in different ways by different compilers.
I.e. in the case of VS and MingW (gcc) it seems that the character constant 'FATE' is first packed in an int in the little endian format with LSbyte holding the 'E'. Then converting the integer constant to char the truncation gives the LSB value, 'E', to print.
PellesC seems to 'optimize' the code using just the first character, 'F'.

For further details check ISO/IEC 9899:2011 §6.4.4.4 Character constants:
Quote
Description:
An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in 'x'.
A wide character constant is the same, except prefixed by the letter L, u, or U.
With a few exceptions detailed later, the elements of the sequence are any members of the source character set; they are mapped in an implementation-defined manner to members of the execution character set.
And
Quote
Constraints:
An integer character constant has type int.
The value of an integer character constant containing a single character that maps to a single-byte execution character is the numerical value of the representation of the mapped character interpreted as an integer.
The value of an integer character constant containing more than one character (e.g. 'ab'), or containing a character or escape sequence that does not map to a single-byte execution character, is implementation-defined.
If an integer character constant contains a single character or escape sequence, its value is the one that results when an object with
type char whose value is that of the single character or escape sequence is converted to type int.

That is to say, the generation of this result is related to the compiler. Right?
According to the contents of the book, it may be more suitable to use codebolocks or MSVC.
Thank you very much for your answers, international friends.

frankie

Quote from: jordantoto on October 25, 2018, 03:20:58 AM
That is to say, the generation of this result is related to the compiler. Right?
This means that the ISO standard lets compilers free to decide how to handle the multibyte sequences.

Quote from: jordantoto on October 25, 2018, 03:20:58 AM
According to the contents of the book, it may be more suitable to use codebolocks or MSVC.
This simply means that if your code must be portable (compilable and runnable on different platforms and with different compilers) you should **avoid** multibyte sequences.
What says your book should be evaluated in the context of the sentence, the chapter and the author intent.
The standard is the only global reference document, the books can contain opinions or preferences, and sometimes may even be completely wrong.

That said observing the behavior of the different compilers it may seem that the choice of MSVC, CLANG and MingW to acquire character constants to int type, and then convert them to char seem more compliant to the standard (see first sentence of ISO/IEC 9899:2011 §6.4.4.4 Character constants constraints), but anyway in the same section it is explained the the compiler can legitimately act differently, as PellesC does.
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

jordantoto

Quote from: frankie on October 25, 2018, 09:59:41 AM
Quote from: jordantoto on October 25, 2018, 03:20:58 AM
That is to say, the generation of this result is related to the compiler. Right?
This means that the ISO standard lets compilers free to decide how to handle the multibyte sequences.

Quote from: jordantoto on October 25, 2018, 03:20:58 AM
According to the contents of the book, it may be more suitable to use codebolocks or MSVC.
This simply means that if your code must be portable (compilable and runnable on different platforms and with different compilers) you should **avoid** multibyte sequences.
What says your book should be evaluated in the context of the sentence, the chapter and the author intent.
The standard is the only global reference document, the books can contain opinions or preferences, and sometimes may even be completely wrong.

That said observing the behavior of the different compilers it may seem that the choice of MSVC, CLANG and MingW to acquire character constants to int type, and then convert them to char seem more compliant to the standard (see first sentence of ISO/IEC 9899:2011 §6.4.4.4 Character constants constraints), but anyway in the same section it is explained the the compiler can legitimately act differently, as PellesC does.

thank you very much!
Thank you for your patience and explanation. Now I understand.

Abraham

Now we know, Pelles C is the only compiler that takes multiple byte sequence in Little Endian format, while most other compilers take them in Big Endian format.

jordantoto

Quote from: Abraham on November 11, 2018, 03:11:28 PM
Now we know, Pelles C is the only compiler that takes multiple byte sequence in Little Endian format, while most other compilers take them in Big Endian format.


No, no, no, C languages are mostly Little endian. You can try this code.


code:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
    union {
        short s;
        char c[sizeof(short)];
    } un;
    un.s = 0x0102;
    if(sizeof(short)==2) {
        if(un.c[0]==1 && un.c[1] == 2)
            printf("big-endian\n");
        else if (un.c[0] == 2 && un.c[1] == 1)
            printf("little-endian\n");
        else
            printf("unknown\n");
    } else
        printf("sizeof(short)= %d\n",sizeof(short));
    exit(0);
}

pelles c,codeblockes,MSVC
It's all a Little Endian

bitcoin

Offtop:
This is one of the reasons why you need to learn Assembly.