Preprocessor command order - compilation

I know that when I have only one source file in C++, preprocessor commands are done in order they were written, but what if I have more than one source file? How is the decision made, which source file should be taken at first? I've written in both source files such code:
#ifndef b
#define b 10
int a = 15;
#endif
and when I compile, there is an error, that variable a has been already defined. But why, if there is a command #ifndef and #endif?

The order that the compiler processes source files is undefined by the language.
I am assuming you get this error in the linker stage. This is because both your source files define a symbol with the same name, and the linker gives up when trying to merge the object code from each file. If your intent is to let at least one of the files have its own separate version of a, declare it in that file as static. Then the linker error should go away as the static a is limited to its own file.

Related

How to "weakly" #include a configuration file?

I'm writing library routines of which some characteristics can be tailored through #include'ing a configuration file. However, I'd like this configuration file to be optional, some default parameters being provided in the source. Here is a typical source beginning:
#include "userconf.h"
#ifndef BUFSIZE
#define BUFSIZE 100
#endif
...
where file userconf.h, if it exists, contains:
#define BUFSIZE 255
Standard compilers (gcc or others) consider a missing #include file an error (and they're right!). In this case, and only for this line, I'd like the compiler to continue without objection since default values are provided for parameters expected from the missing configuration file.
Is there a way to do this?
Note: I don't mind checking for this existence of the file from the make system (I'm using CMake) and passing a -Doption if that's easier to do (but, please, provide CMake directives for it, I'm not familiar with it and open documentation gives a hard time to grab the whole picture).
I found the answer "by accident" when including the wrong file.
You make profit of the multiple include directory search feature of the compiler (aka. -I option). You arrange your -I option list in such a way that there is a directory, preferentially at the end of the chain, containing a skeletal version of the configuration file.
For example, directory default/ contains the following userconf.h:
#define BUFSIZE 255
and the developement directory develop/ contains the live userconf.h:
#define BUFSIZE 100
Then, the source file of the original question may be compiled with
gcc source.c -Idevelop -Idefault ...
and -Idevelop may be omitted if it is part of the default searched directories.

gcc: passing list of preprocessor defines

I have a rather long list of preprocessor definitions that I want to make available to several C programs that are compiled with gcc.
Basically I could create a huge list of -DDEF1=1 -DDEF2=2 ... options to pass to gcc, but that would create a huge mess, is hard to use in a versioning-system and may at some time in the future break the command line length limit.
I would like to define my defines in a file.
Basically the -imacros would do what I want except that it only passes it to the first source file: (below from the gcc documentation):
-include file Process file as if #include "file" appeared as the first line of the primary source file. However, the first directory searched
for file is the preprocessor's working directory instead of the
directory containing the main source file. If not found there, it is
searched for in the remainder of the #include "..." search chain as
normal. If multiple -include options are given, the files are included
in the order they appear on the command line.
-imacros file Exactly like -include, except that any output produced by scanning file is thrown away. Macros it defines remain defined.
This allows you to acquire all the macros from a header without also
processing its declarations. All files specified by -imacros are
processed before all files specified by -include.
I need to have the definitions available in all source files, not just the first one.
Look at the bottom of this reference.
What you might want is the #file option. This option tells GCC to use file for command-line options. This file can of course contain preprocessor defines.
Honestly - it sounds like you need to do a bit more in your build environment.
For example, one suggestion is that it sounds like you should create a header file that is included by all your source files and #define all your definitions.
You could also use -include, but specify an explicit path - which should be determined in your Makefile/build environment.
The -imacros would work, if your Makefile were building each source file independently, into its own object file (which is typical). Its sounds like you're just throwing all the sources into building a single object.

gcc recompile "make" result no changes

i'm using cs50 appliance.
i've tried to write a new file test.c , found as long as i include int i line, it doesn't generate a new file test, if i remove that line and make again, it can generate test file. then i made changes on the test file, it still output the original file result, no reflect the new changes.
#include <stdio.h>
#include <cs50.h>
int
main (void)
{
printf("Number: \n");
int i = GetInt();
}
it was running properly before though... anyone can help please?
Apparently your default rules for make run the compiler on test.c.
The compiler notices that you are assigning a value to variable i, but you never use that value in any way; it would normally report this as a warning.
Apparently either your compiler or make are configured in such a way that this warning becomes a fatal error to make.
The remedy is to use the variable. It looks as though you need to pick up a book on the C programming language, or follow a course, if that's not what you're doing already.

Pre-processing C code with GCC

I have some C source files that need to be pre-processed so that I can use another application to add Code Coverage instrumentation code in my file.
To do so, I use GCC (I'm using this on a LEON2 processor so it's a bit modified but it's essentially GCC 3.4.4) with the following command line:
sparc-elf-gcc -DUNIT_TEST -I. ../Tested_Code/0_BSW/PKG_CMD/MEMORY.c -E > MEMORY.i
With a standard file this works perfectly, but this one the programmer used a #ifndef UNIT_TEST close and no matter what I do the code won't be pre-processed. I don't understand why since I'm passing -DUNIT_TEST to GCC explicitly defining it.
Does anyone have any clue what could cause this? I checked the resulting .i file and as expected my UNIT_TEST code is not present in it so I get an error when instrumenting it.
Anything wrapped in an #ifndef will only be parsed if it's NOT defined so you need to remove that definition to get all the code that is inside that block. GCC can't spit out preprocessed info for all the #ifdef and #ifndef if at preprocessing times symbols are/aren't defined.

Fortran query and print out function or subroutine name

Is it possible in Fortran to query the name of the function or subroutine that I am in? I.e., what do I put in place of '???' to get it to print 'my_subroutine' on the screen?
subroutine my_subroutine()
write(*,*) ???
end subroutine my_subroutine
I am trying to find a way to implement a custom debugger/profiler using nothing but a text editor's search and replace mechanism. Programmatically querying my position in the code would be helpful.
No, you can't. What you want to achieve is called reflection and it is not available in Fortran (nor in C or C++ for what matters).
You can use the preprocessor to print out the file name and line number. You might want take advantage of the predefined preprocessor symbols __LINE__ and __FILE__. Here's an example:
A preprocessor macro is defined in header file (so that it can be used in multiple locations), call it errormsg.h:
#define ERRORMSG(msg) write(0,'("There was an error at ",I4," in file ",/,A,/,"Error message: ",A)') __LINE__,__FILE__,msg
Then you can include this header file in your program, library or module files, for example:
#include "errormsg.h"
program main
ERRORMSG("not really an error...")
call foo()
end program
subroutine foo()
ERRORMSG("not an error too!")
end subroutine
The ERRORMSG("not really an error...") seems like weird syntax for fortran code, but it get's replaced by the c-preprocessor using the macro definition. So when this is compiled, it looks like:
write(0,'("There was an error at ",I4," in file ",/,A,/,"Error message: ",A)') __LINE__,__FILE__,"not really an error"
For my ERRORMSG macro, I chose to use the 0 file unit to print to stderr. You obviously have the freedom to write the message how ever you like, as long as it results in syntactical correct FORTRAN code.
Getting this to compile requires you to pass flags to the compiler, and they differ slightly from compiler to compiler. This worked for me, for example:
gfortran -cpp -o errorTest errorTest.f90
That is, for gfortran, -cpp invokes the c-preprocessor before compiling. The output from the above program looks like this:
There was an error at 5 in file
errorTest.f90
Error message: not really an error...
There was an error at 13 in file
errorTest.f90
Error message: not an error too!
This might have the effect you are looking for, especially if you write only one subroutine per file.
I found an easy semi-automated way out of this situation: use regex to add a hardcoded definition of __FUNCTION__ right after the SUBROUTINE declaration. Done from within the makefile will take care that every compilation refreshes the __FUNCTION__ macro.
Suppose we have a F77 listing that looks like this
file 'my-file.F'
SUBROUTINE my_sub(var1, var2, var3)
INCLUDE 'some-include.PRM'
INTEGER var1
INTEGER var2
! the rest of my code here
WRITE(*,*)__FUNCTION__
END SUBROUTINE
I want to convert it to
file 'my_file.F.F'
SUBROUTINE my_sub(var1, var2, var3)
#undef __FUNCTION__
#define __FUNCTION__ "my_sub"
INCLUDE 'some-include.PRM'
INTEGER var1
INTEGER var2
! the rest of my code here
WRITE(*,*)__FUNCTION__
END SUBROUTINE
Note the amended code is now located in another source file: my-file.F.F
To do this I added the following lines to 'Makefile'
my-file.o: my-file.F
perl -pne 's/^(\s+SUBROUTINE\s*)([^(]+)(\(.*\))/$$1$$2$$3\n#undef __FUNCTION__\n#define __FUNCTION__ _S($$2)/ixms' $< > $<.F; \
$(FC) $(CPPFLAGS) $(FCFLAGS) -c $<.F -o $#
Assuming FC is defined as the fortran compiler executable, this should perform the following procedure on all the subroutines in the file:
undefine a __FUNCTION__ macro that was possibly defined earlier.
Add a __FUNCTION__ directive two lines below the SUBROUTINE definition, containing the subroutine's name.
save the file under another name.
compile the new source into the required object file.
The result should be my-file.o in this case.
You may have noticed that I'm using the macro _S() as well. This is a 'stringify' macro. You just need to add it to the top of your fortran file (I place it inside a config.h that I include everywhere)
There is a different implementation for GNU and intel:
#ifdef __INTEL_COMPILER
#define _S(x) #x
#else
#define _S(x) "x"
#endif
There are sometimes non-standard features in compilers to help you to print where you currently are. These are highly compiler specific and should be used only for debugging.
In gfortran you can use subroutine BACKTRACE. From the manual:
BACKTRACE shows a backtrace at an arbitrary place in user code.
Program execution continues normally afterwards.
The output will look like an error message, but it may be helpful.
Why don't you just hard write the name of the subroutine you're in, in the WRITE statement?
You cannot programmatically (dynamically) give or change the name of the subroutine, therefore I see no reason to try to access it either that way (about that: while I'm not sure that it is impossible to access it somehow, I'm quite sure that it is the wrong way to go ... you will cause yourself more trouble going that way, than just hard coding it).
Btw, why are you trying to print it out anyway? Wouldn't a well phrased diagnostic message be more informative?

Resources