What is this value? [duplicate] - c

This question already has answers here:
How printf("%d","<string>") work in C?
(2 answers)
Closed 4 years ago.
printf("%d", "10+10");
then I get "17661648" and similar thing in too
printf("%d", "Hello");
What is this value?
sum of "1,0,+,1,0" "H,e,l,l,o" as ASCII code in decimal number? or just a garbage value?

According the the C11 standard n1570 (see its §7.21.6.1) you've got undefined behavior (UB), which is also documented here or in printf(3). So be very scared, since arbitrarily bad things could happen. So take the habit of reading the documentation of every function that you are using.
If you ask your compiler to disassemble the generated form of your program (e.g. by compiling with gcc -S -O -fverbose-asm if you use GCC, on Linux/x86-64) you'll discover that the address of the string literal "10+10" is passed (on 64 bits) and then truncated (inside printf, because of the %d) to an int. So the 17661648 could correspond to the lowest 32 bits of that address.
Details are of course implementation specific (and could vary from one run to the next one because of ASLR, depends upon the compiler and the ABI and the target system). To actually understand and explain the behavior requires diving into many details (your particular computer, your particular compiler and optimization flags, your particular operating system, the compiler generated assembler & machine code, your particular C standard library, etc....) and you don't want to do that (because it could take years).
You should take several hours to read more about UB. It is an essential notion to understand when programming in C, and you should avoid it.
Any good compiler would have warned you, and then you should improve your code to get no warnings. If using GCC, be sure to compile with gcc -Wall -Wextra -g to get all warnings and debug info. Then use the gdb debugger to understand the actual behavior of your program on your system. In all cases, be sure to configure your C compiler to enable all warnings and debug info, and learn to use your debugger. Read How To Debug Small Programs.

Someting like this should work:
printf("Hello");
total = 20;
printf("10+10 = %d", total);

Related

Needs debugging symbols for __alignof__

I'm debugging the glibc library. I've built it with -g3 -O flags. I can print most macros, but not this one. I'm debugging malloc(), and there are a lot of macros that use __alignof__. But I can't find its definition anywhere in glibc source code. Here is an example:
(gdb) p MALLOC_ALIGN_MASK
No symbol "__alignof__" in current context.
And also I got the same problem with __builtin_offsetof. But this one is an built in macro. So the 2 cases are a bit different. Solving this problem will speed up my debugging a bit.
You won't get any debugging information. Since __alignof__ is, like sizeof, only known at compile-time. See alignof from <stdalign.h>
Even by recompiling GCC itself, you won't get it (there is no debugging information available). __alignof__ is processed at compile time (so __alignof__ (double) is replaced by 8 during compilation, for x86-64 ABI).
You could guess by yourself the expanded value of MALLOC_ALIGN_MASK.
You could define a const int my_malloc_align_mask = MALLOC_ALIGN_MASK; and use p my_malloc_align_mask in the debugger.
I'm debugging the glibc library.
This is weird. You should trust the glibc library to behave as documented (yes, beware of undefined behavior).
GDB only has a very approximate implementation of C and C++. It does not use the same C and C++ parser as GCC, so some things are missing, including this GCC extension. GDB recognizes _Alignof, but it is not exactly the same as __alignof__. But it will work in this case, so you could change the glibc sources to use it.
LLDB uses the Clang parsers and therefore does not suffer from this particular problem, but will not help you here because apparently, the debugger does not recognize the DWARF data generated by the -g3 option, so the macro information is missing from the executable.

GCC optimization flag problems

I am having a problem with some C code built with gcc compiler. The code in question has an enum, whose values are used as cases in a switch statement to configure an object. Fairly standard stuff.
When I compile the code using the -O0 option flag, everything builds and runs correctly no problem. However, when the flag is set to -O2 the code no longer works as expected.
When I step through the code and put a watch on the local variables, the enum, which should be only be one of three enum values, is actually -104! This causes the program to fail to configure the object.
Has anyone encountered this before who could provide some guidance? I haven't encountered this before and would appreciate if someone could explain why the compiler does this so I can make any necessary changes.
Snippet of code in question:
value = 0u;
switch(test_config) {
case DISABLE:
break;
case INTERNAL:
value = 1u;
break;
case EXTERNAL:
value = 2u;
break;
default:
valid = FALSE;
break;
}
if (valid) {
configure_test(value);
}
Enum in question:
typedef enum {
DISABLE,
INTERNAL,
EXTERNAL
} test_config_t;
This is the code that is causing the problem. I initially didn't include it because I didn't want the question to be please fix my code, rather I have been googling looking for reasons why gcc optimisation flags would produce different results for the same piece of code and haven't found anything particularly helpful. Also I am not at my computer and had to type this on my phone which also doesn't help. So I came here because there are experts here who know way more than me that could point me in the right direction.
Some more info that I probably should have included. The code runs on hardware which also might be the problem and I am looking into that as well. When ran from FSBL the code works with -O0, but not with -O2. So it may be hardware, but then I don't know why it works one way not the other.
You don't give enough details (since your question don't show any actual code, it should have some MCVE) but you very probably have some undefined behavior and you should be scared.
Remember that C11 or C99 (like most programming languages) is defined by an explicit specification (not only by the concrete behaviour observed on your code) written in English and partly defining the runtime behaviour of a valid C program. Read n1570.
I strongly recommend reading Lattner's blog What Every C programmer should know about Undefined Behavior before even touching or compiling your source code.
I recommend at least compiling with (nearly) all warnings and debug info, e.g. with gcc -Wall -Wextra -g, then improve the code to get no warnings, and run it under the gdb debugger and valgrind. Read more about Invoking GCC. You may also use (temporarily) some sanitizer instrumentation options, notably -fsanitize=undefined and -fsanitize=address. You could also add -std=gnu99 and -pedantic to your compiler flags. Notice that gdb watchpoints are a very useful debugger feature to find why a value has changed or is unexpected.
When you compile for release or for benchmarking with optimizations enabled, keep also the warning flags (so compile with gcc -O2 -Wall -Wextra); optimizations might give extra warnings which you should also correct. BTW, GCC accepts both -O2 and -g at the same time.
When you observe such issues, question first your own code before suspecting the compiler (because compilers are very well tested; I found only one compiler bug in almost 40 years of programming).

Is this a valid C program?

I wrote a program, where the size of an array is taken as an input from user.
#include <stdio.h>
main()
{
int x;
scanf("%d", &x);
int y[x];
/* some stuff */
}
This program failed to compile on my school's compiler Turbo C (an antique compiler).
But when I tried this on my PC with GNU CC, it compiled successfully.
So my question is, is this a valid C program? Can I set the size of the array using a user's input?
It is a valid C program now, but it wasn't 15 years ago.
Either way, it's a buggy C program because x is used without any knowledge of how large it might be. The user can input a malicious value for x and cause the program to crash or worse.
C99 gives C programmers the ability to use variable length arrays,which are arrays whose sizes are not known until run time. --C:A Reference Manual
c90 does not support variable length arrays you can see this using this command line:
gcc -std=c90 -pedantic code.c
you will see an error message like this:
warning: ISO C90 forbids variable length array ‘y’ [-Wvla]
but c99 this is perfectly valid:
gcc -std=c99 -pedantic code.c
Instead of asking whether this is strictly valid C code, it may be better to ask whether it is good C code. Although it is valid, as you have seen, a number of compilers do not support variable length arrays.
Variable length arrays are not supported by a number of modern compilers. These include Microsoft Visual Studio and some versions of the IBM XL compilers. As you have found, variable length arrays are not entirely portable. That's fine if the code will only be used on systems that support the feature but not if it has to be run on other systems. Instead, it may be better to allocate the array with constant size using a reasonable limit or use a malloc and free to create the array in portable manner.

Performance difference between C program executables created by gcc and g++ compilers

Lets say I have written a program in C and compiled it with both gcc (as C) and g++ (as C++), which compiled executable will run faster: the one created by gcc or by g++? I think using the g++ compiler will make the executable slow, but I'm not sure about it.
Let me clarify my question again because of confusion about gcc:
Let's say I compile program a.c like this in the terminal:
gcc a.c
g++ a.c
Which a.out executable will run faster?
Firstly: the question (and some of the other answers) seem to be based on the faulty premise that C is a strict subset of C++, which is not in fact the case. Compiling C as C++ is not the same as compiling it as C: it can change the meaning of your program!
C will mostly compile as C++, and will mostly give the same results, but there are some things that are explicitly defined to give different behaviour.
Here's a simple example - if this is your a.c:
#include <stdio.h>
int main(void)
{
printf("%d\n", sizeof('x'));
return 0;
}
then compiling as C will give one result:
$ gcc a.c
$ ./a.out
4
and compiling as C++ will give a different result (unless you're using an unusual platform where int and char are the same size):
$ g++ a.c
$ ./a.out
1
because the C specification defines a character literal to have type int, and the C++ specification defines it to have type char.
Secondly: gcc and g++ are not "the same compiler". The same back end code is used, but the C and C++ front ends are different pieces of code (gcc/c-*.c and gcc/cp/*.c in the gcc source).
Even if you stick to the parts of the language that are defined to do the same thing, there is no guarantee that the C++ front end will parse the code in exactly the same way as the C front end (i.e. giving exactly the same input to the back end), and hence no guarantee that the generated code will be identical. So it is certainly possible that one might happen to generate faster code than the other in some cases - although I would imagine that you'd need complex code to have any chance of finding a difference, as most of the optimisation and code generation magic happens in the common back end of the compiler; and the difference could be either way round.
I think they they will both produce the same machine code, and therefore the same speed on your computer.
If you want to find out, you could compile the assembly for both and compare the two, but I'm betting that they create the same assembly, and therefore the same machine code.
Profile it and try it out. I'm certain it will depend on the actual code, even if it would require potentially a really weird case to get any different bytecode. Though if you don't have extern C {} around your C code, and or works fine in C, I'm not sure how "compiling it as though it were C++" could provide any speed, unless the particular compiler optimizations in g++ just happen to be a bit better for your particular situation...
The machine code generated should be identical. The g++ version of a.out will probably link in a couple of extra support libraries. This will make the startup time of a.out be slower by a few system calls.
There is not really any practical difference though. The Linux linker will not become noticeably slower until you reach 20-40 linked libraries and thousands of symbols to resolve.
The gcc and g++ executables are just frontends, they are not the actual compilers. They both run the actual C or C++ compilers (and ld, ar, whatever is needed to produce the output you asked for) based on the file extensions. So you'll get the exact same result. G++ is commonly used for C++ because it links with the standard C++ library (iostreams etc.).
If you want to compile C code as C++, either change the file extension, or do something like this:
gcc test.c -otest -x c++
http://gcc.gnu.org/onlinedocs/gcc-3.3.6/gcc/G_002b_002b-and-GCC.html
GCC is a compiler collection. It is mainly used for compilation of C,C++,Ada,Java and many more programming languages.
G++ is a part of gnu compiler collection(gcc).
I mean gcc includes g++ as well. When we use gcc for compilation of C++ it uses g++. The output files will be different because the G++ compiler uses its own run time library.
Edit: Okay, to clarify things, because we have a bit of confusion in naming here. GCC is the GNU Compiler Collection. It can compile Ada, C++, C, and a billion and a half other languages. It is a "backend" to the various languages "front end" compilers like GNAT. Go read the link i made at the top of the page from GCC.GNU.Org.
GCC can also refer to the GNU C Compiler. This will compile C++ code if given the -lstdc++ command, but normally will choke and die because it's not pulling in the C++ libraries.
G++, the GNU C++ Compiler, like the GNU C Compiler is a front end to the GNU Compiler Collection. It's difference between the C Compiler is that it automatically includes those libraries and makes a few other small tweaks, because it's assuming it's going to be fed C++ code to compile.
This is where the confusion comes from. Does this clarify things a bit?

Are macro definitions compatible between MIPS and Intel C compiler?

I seem to be having a problem with a macro that I have defined in a C program.
I compile this software and run it sucessfully with the MIPS compiler.
It builds OK but throws the error "Segmentation fault" at runtime when using icc.
I compiled both of these on 64 bit architectures (MIPS on SGI, with -64 flag and icc on an intel platform).
Is there some magic switch I need to use to make this work correctly on both system? I turned on warnings for the intel compiler, and EVERY one of the places in my program where a macro is invoked throws a warning. Usually something along the lines of mismatched types on the macro's parameters (int to char *) or some such thing.
Here is the offending macro
#define DEBUG_ENTER(name) {tdepth++;
if(tnames[tdepth] == NULL) tnames[tdepth] = memalign(8, sizeof(char)*MAXLEN);
strcopy(tnames[tdepth],name);
FU_DEBUG("Entering \n");}
This basically is used for debugging - printing to a log file with a set number of tabs in based on how many function calls there are. (tdepth = tab depth)
I did some checking around in man pages. it seems like memalign is only supported on IRIX. This may be my problem. I am going to track it down.
This might have to do with the system's "endianness." Looking here it seems that MIPS has switchable endianness. I'm not sure if you are using the correct endianness already, but if you aren't, you will DEFINATELY have problems.
This might be a byte order issue. MIPS can be big endian but intel is little endian.
It sounds like the array tnames is an array of int. If you're assigning pointers to it, it should be an array of a pointer type - in this case probably char * is appropriate.
(Also, strcopy() isn't a standard function - are you sure you don't mean strcpy()?)

Resources