Is there a way to see what the expanded code will look like after preprocessing?
Found many answers to my question online but all of them used a lot of terms which were completely alien to me.
Seeing expanded C macros
Determine the expansion of a C macro
I am a complete beginner in programming. Learning C from 'Let us C' by Y.K. Currently in the 12th chapter
'C Preprocessor'.
Can someone explain this in simple terms or should I just leave it for now and get back to it later?
using Code:Blocks as the IDE and gcc as the compiler.
Edit:-
#include<stdio.h>
#define AREA(x) (3.14*x*x)
int main()
{
int r1=1,r2=2;
float ar1,ar2;
ar1=AREA (r1);
printf(" %f",ar1);
ar2=AREA (r2);
printf(" %f",ar2);
printf(" %f",ar1/ar2);
printf(" %f",AREA (r1)/AREA (r2));
}
Compile your code from the terminal, with the -E flag: gcc my_code.c -E.
This will print the preprocessed code directly to the terminal. If you want to save it to a file instead, add something like -o result.txt at the end.
Read the documentation of the GCC compiler.
Read also some C reference website.
There is a chapter about Invoking GCC. Spend an hour to read it.
You also want to read the documentation of the CPP preprocessor, and probably of GNU binutils.
You could compile your C file ems.c using gcc -Wall -Wextra -g -H ems.c -o ems-prog. Once you have no warnings, use the GDB debugger to understand the behavior of your executable ems-prog
You could run gcc -Wall -Wextra -g -C -E ems.c -o ems.i to obtain, inside the ems.i file, the preprocessed form of ems.c
You can run compilation commands in some terminal emulator.
Later, you want to use GNU make (or ninja) or some other build automation tool to drive compilation commands. Of course, you need to read their documentation.
Study for inspiration the source code of existing free software coded in C, for example GNU bash.
Related
I want to be able to pass arguments to GCC from my C source code, something like this...
// pass the "-ggdb" argument to GCC (I know this won't work!)
#define GCC_DEBUG_ARG -ggdb
int main(void) {
return 0;
}
With this code I'd like to simply run gcc myfile.c which would really run gcc myfile.c -ggdb (as the "-ggdb" argument has been picked up from the C source code).
I'm not interested in using make with the CFLAGS environment variable, I just want to know if its possible to embed GCC options within C source code
What you want to do is not possible in general.
However, recent GCC (e.g. GCC 8 in end of 2018) accepts many options and some of them could be passed by function attributes or by function specific pragmas (However, they don't accept -g but do accept -O2).
Also, you can use -g in every compilation (with GCC, it is mixable with optimization flags such as -O2; so runtime performance won't suffer. Of course the -g will increase compile time and size of produced object file). Notice that (on Linux) the DWARF debug information is visible in the generated assembler file (e.g. try to compile your foo.c with gcc -Wall -g -O -S -fverbose-asm foo.c, look into the generated foo.s, and repeat by removing the -g)
I'd like to simply run gcc myfile.c
That is a very bad habit. You should run gcc -Wall -Wextra -g myfile.c -o myprog to get all warnings (you really want them) and debug info in your executable myprog. Read How to debug small programs before continuing coding your program.
I'm not interested in using make with the CFLAGS environment variable
But you really should. Using make or some other build automation tool (e.g. ninja, omake, rake, etc, etc....) is, in practice, the conventional and usual way of using GCC.
Alternatively, on Linux, write a tiny shell script doing the compilation (this is particularly worthwhile if your program is a single source file; for anything bigger, you really should use some build automation tool). At last, if you use emacs as your source code editor, you could add a few lines of comments (like at end of my manydl.c example) specifying Emacs file variables to tune the compilation (done from emacs)
If these conventions surprise you, read about the Unix philosophy then study -for inspiration- the source code of some existing free software (e.g. on github, gitlab, or in your favorite Linux distribution).
At last, GCC itself is a free software project (but a huge one of more than five millions lines of mostly C++ source code). So you can improve it the way you desire (if you follow its GPLv3+ license), after having studying somehow its source code. That would take you several months (or years) of work (because GCC is very complex to understand).
See also this answer to a related question.
You might also (but I recommend not to, because it is very confusing) play tricks with your PATH variable and have some directory there -e.g. $HOME/bin/, ahead of /usr/bin/ which contains /usr/bin/gcc, with your shell script named gcc; but don't do that, you'll be confused. Instead write some "generic" mygcc shell script which would run /usr/bin/gcc and add appropriate flags to it (I believe it is not worth the effort).
I wanted to compile the below code in VS Code, but I'm fetching this error using "code runner". I've looked up everywhere, but it didn't solve my issue.
I want to implement this T(n) = 2T(n/2) + nlog(n)
q2.c
// b. T(n) = 2T(n/2) + nlog(n)
#include <stdio.h>
#include <math.h>
int func(double n)
{
return (2*func(n/2) + n*(log(n)));
}
int main()
{
double n, result;
printf("Enter the value of 'n' \n");
scanf("%lf",&n);
printf("Hey");
result = func(n);
printf("%lf \n",result);
printf("Hey");
return 0;
}
Console:
user#user-H310M-DS2:~/Desktop/C programming/Assignments$ cd "/home/user/Desktop/C programming/Assignments/" && gcc q2.c -o q2 && "/home/user/Desktop/C programming/Assignments/"q2
/tmp/ccnNXN3L.o: In function `func':
q2.c:(.text+0x3a): undefined reference to `log'
collect2: error: ld returned 1 exit status
Visual studio code has nothing to do with your issue, you are not compiling with it. Because it is an IDE (or source code editor), not a compiler. I guess you are using it on some Linux or POSIX system. BTW my preferred source code editor is GNU emacs. So your IDE is running some compilation commands (and you need to understand which ones and what these commands are doing). You could run these commands in a terminal (and that actually might be simpler).
As your console logs shows, you are compiling with GCC. Some gcc command has been started (by Visual studio code probably).
Read carefully about Invoking GCC. Order of arguments matters a lot!
You should compile your code with
gcc -Wall -Wextra -g q2.c -lm -o q2
Let me explain this a bit:
gcc is your compiler front-end (the actual compiler is cc1 but you never use it directly; you ask gcc to run it)
-Wall asks for almost all warnings
-Wextra asks for extra warnings. You'll be happy to get them
-g asks for debugging information in DWARF. You really want to be able to use the gdb debugger, and gdb practically needs debugging information.
q2.c is the source file of your sole translation unit
-lm is for your math library. You are using log(3) and its documentation mention that.
-o q2 tells gcc to put the executable in q2 (the actual work is done by the ld linker invoked by gcc)
How to configure visual studio code to use that command is your business. You could otherwise type the above command in a terminal. Then you can run your q2 program by typing ./q2 in a terminal for your shell (and you could use gdb on it).
Notice that gcc is starting other programs (like cc1, as, ld). If you want to understand which ones, insert -v after gcc in the command above.
Be sure to read the documentation of every function you are using (so read printf(3), scanf(3), log(3) at least...) and of every program you are using (e.g. of gcc and of Visual studio code).
Once you'll write bigger programs made of several translation units (e.g. foo.c, bar.c, gee.c), you would want to use some build automation tool (because compiling all of them every time with gcc -Wall -Wextra -g foo.c bar.c gee.c -lm -o qqq is possible, but inconvenient). You could learn to use GNU make (or ninja).
Read How to debug small programs. Don't expect your program to work as you want at first.
BTW, study the source code of some existing free software programs (but start with simple projects, e.g. on github, of less than a hundred thousand lines). This could teach you many useful things.
I'm not sure how VSCode compiles programs, but since it uses GCC, it's likely that you need to link the math library libm when compiling, by supplying an argument -lm to GCC.
Just a tweak to code runner's settings.json under file->preferences->settings of VS Code :
I've added the below line
"code-runner.executorMap":
{
"c": "cd $dir && gcc -Wall -Wextra -g $fileName -lm -o $fileNameWithoutExt && $dir$fileNameWithoutExt",
}
It's working now.
On this beginner tutorial at TutorialsPoint, it says to save the code as test.c and compile it using "$gcc test.c -o demo" command at CMD.
But I don't have $gcc. What is it?
Let's split this into parts:
$ is a character indicating that the shell is ready to receive a command. It is not part of the command.
gcc is an executable executing the GNU C compiler from the GCC toolchain.
test.c -o demo are arguments supplied to gcc.
The GCC toolchain is only available natively for GNU systems such as Linux. Using MinGW or CygWin you can ape its functionality, though.
Notes:
A nice comment, which I second, to your question by #iharob:
Don't use gcc test.c -o demo specially if you are a beginner, use gcc -Wall -Wextra -Werror test.c -o demo.
The additional switches make the compiler point out more warnings.
GCC (GNU Compiler Collection. Upper case.) is a set of compilers, that can compile several languages.
gcc (lower case) is a command that compile the code you wrote, using the C compiler that GCC includes, into a working C program. Similar commands are g++ for C++ code, gcj for Java code, etc.
Note GCC is intended for Linux or other Unix-like systems (You can use it in Mac OS X with the help of xcode). If you are using Windows, consider [MinGW] (http://www.mingw.org/) or CygWin https://www.cygwin.com/.
As a beginner, if you still have trouble, consider use Dev-C++, an IDE (integrated development environment) that compiles C and C++. It does all the compiler things for you.
I want to do some program analysis project on C program. So far, I want to get one C program as the input for clang, and then I use LLVM to make some analysis.
I want to do some experiment on gnu unix utility. For example:
diff (https://www.gnu.org/software/diffutils/).
For example, when I want to do analysis on src/diff.c:
My command is: clang -emit-llvm -O0 -c diff.c -o test.bc
However I will get the below error:
./system.h:21:10: fatal error: 'config.h' file not found
which seems that clang cannot find config.h.
So my question is how to parse single program in a GNU utility?
Do I need to write a Makefile or where can I find something like config.h?
I need to compile a program in MS DOS. I have Borland Editor, I can compile it using Alt+F9 but the things is what it do at the backend. I want to compile it in MS DOS. I m trying this:
c:\tc\bin>tcc -o hello.exe hello.c
where hello.c is is my file, hello.exe the file I want to produce. Its not working, what shouldI do? and also please tell me also how do I compile .cpp file manually from MS DOS.
If I remember correctly, Borland/Turbo C compiler's command line options didn't look like gcc options. You should try tcc /? for a command line help.
Turbo C++ Version 3.00 Copyright (c) 1992 Borland International
Syntax is: TCC [ options ] file[s] * = default; -x- = turn switch x off
-1 80186/286 Instructions -2 80286 Protected Mode Inst.
-Ax Disable extensions -B Compile via assembly
-C Allow nested comments -Dxxx Define macro
-Exxx Alternate Assembler name -G Generate for speed
-Ixxx Include files directory -K Default char is unsigned
-Lxxx Libraries directory -M Generate link map
-N Check stack overflow -O Optimize jumps
-P Force C++ compile -Qxxx Memory usage control
-S Produce assembly output -Txxx Set assembler option
-Uxxx Undefine macro -Vx Virtual table control
-X Suppress autodep. output -Yx Overlay control
-Z Suppress register reloads -a Generate word alignment
-b * Treat enums as integers -c Compile only
-d Merge duplicate strings -exxx Executable file name
-fxx Floating point options -gN Stop after N warnings
-iN Max. identifier length -jN Stop after N errors
-k Standard stack frame -lx Set linker option
-mx Set Memory Model -nxxx Output file directory
-oxxx Object file name -p Pascal calls
-r * Register variables -u * Underscores on externs
-v Source level debugging -wxxx Warning control
-y Produce line number info -zxxx Set segment names
C:\TC\BIN>
So, I think you should type:
tcc hello.c for C programs and tcc -P hello.cpp for C++ programs.
I belive this things must work
c:\tc\bin\tcc -c File.c \\ To generate objective file
c:\tc\bin\tcc -o File.obj \\ To generate exe from obj and please use .obj and not .o
c:\tc\bin\ tcc -run File.c \\ to generate exe file without .obj file
c:\tc\bin\File.exe \\ to run the exe file
I dont know why the
tcc -o good.exe File.obj \\not working, the error is good.exe file not found
I think we cant give a name to .exe file in tcc command line prompt.but its possible in gcc. I dont know about TCC much. If i find it i will let you know it !
Just take a look at these http://bellard.org/tcc/tcc-doc.html#SEC3. This is what I found on google . and googling makes you more powerful so keep on googling the things when you dont know .
Thanks
Further to Prof Falken's answer
tcc file.c <-- will compile in C
tcc file.cpp <-- will compile in cpp
tcc file.ext where .ext is anything other than cpp, will compile in C Unless --P is used then cpp is used to compile it, in which case .cpp is used, even if the extension is .c
I am running TCC in a VM and can't copy/paste from there here. But your test should find the same result as mine, if not, then perhaps I erred, but you can test for yourself given this code that works in C and not CPP, and code that works in CPP and not C. You can then experiment with changing the extension, and using -P or not.
The following code works in C only
conly.c
(A C++ expert told me re the following example, works in C and not C++, because C allows void* -> T* conversions. C++ does not)
#include <stdio.h>
#include <stdlib.h>
void main() {int *x=malloc(4);}
The following code works in C++ only
cpponly.cpp
#include <stdio.h>
void main() {
int a=9;
int& b=a;
printf("b=%d",b);
}