Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
Let's say I am creating a program and a makefile, and I want to be able to create three different executables with different names that all do different things, all with the same source file. Is this at all possible?
Option 1
Write a program that examines argv[0] to see what name it has been executed with and branches based on that:
#include <stdio.h>
#include <string.h>
int main(int argc, char *argv[])
{
size_t length = strlen(argv[0]);
if (3 <= length && strcmp(argv[0]+length-3, "foo") == 0)
printf("This is the foo program. It does foo things.\n");
else if (3 <= length && strcmp(argv[0]+length-3, "bar") == 0)
printf("This is the bar program. It does bar things.\n");
else
printf("This is the default program. It does default things.\n");
}
Compile the program and call the executable x or some other name.
Presuming you are using some version of Unix, link the file to more names:
ln x foo
ln x bar
Run the program with various names:
% ./x
This is the default program. It does default things.
% ./foo
This is the foo program. It does foo things.
% ./bar
This is the bar program. It does bar things.
Option 2
Use preprocessor symbols to build different programs. The source code can be:
#if Option == 1
#include "Program1.c"
#elif Option == 2
#include "Program2.c"
#else
#include "ProgramDefault.c"
#endif
The source code does not have to be in separate files. The above is only an example, and all of the source code could be in the file directly instead of included with #include.
With GCC and Clang, you can define a preprocessor symbol with -DOption=value on the command line to compile the program. The rules in a makefile can build the different programs by using different values in the compile command.
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
I'm trying to clean up my project, to help expand it further, but there's about 200 lines of variables definitions, calculations and writing into arrays before starting the actual application, and it's an absolute mess.
Is there a way to put all of this into another file, and include these definitions in the file I'd like to use it in (and only that file, to avoid conflicts) ?
I tried creating something like "levelVars.c" and including it in the "level.c" file, but all I get is a bunch of errors.
There's also some custom types and SDL types in here, so..it might cause problems.
The reason I want to do all this is to clean up the file : I'm having trouble navigating between everything with such a massive block of variables.
I also can't reduce their numbers, as I need them all ; every variable is taken in by some functions and used by others, so I can't just reduce their scope and clean up this way. Well, I could maybe cut down ten variables like this, but it won't help much.
The beginning looks like this :
int trackSomething = 0;
int trackSomethingElse = 0;
int yetAnotherCount = 0;
bool active = false;
bool andAnother = false;
bool iThinkYouGotIt = false;
int arr[SIZE_1][SIZE_2];
for(int i = 0 ; i < SIZE1 ; i++)
{
for(int j = 0 ; j < SIZE2 ; j++)
{
arr[i][j] = 0;
}
}
....
while(active)
{
// The actual loop that does something meaningful with all this
}
Don't use the pre-processor to do includes. Use the linker:
$ cat variables.h
extern int d;
$ cat variables.c
int d = 57;
$ cat main.c
#include "variables.h"
#include <stdio.h>
int main(void) { printf("d = %d\n", d); return 0; }
$ gcc -c main.c
$ gcc -c variables.c
$ gcc main.o variables.o
$ ./a.out
d = 57
Your request that the variables only be available to one translation unit is somewhat difficult to enforce, and you really shouldn't try. (Ab)using the pre-processor to include the variable definitions with a #include to force the definitions and their usage to all be in the same translation unit will do it, but your code will be better organized if you don't do that.
I don't think that you'll achieve what you are looking for. You can define a variable in levelVars.c:
int count;
And you want to use it later in another file, don't you? Well, to do that you must reference it again in that new file but saying that the variable "comes from another file" by using extern:
extern int count;
So in the end you will end up with the same 200 variables in your file, only with extern in front of them...
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 3 years ago.
Improve this question
Note: This is not a question to ask for a program, It asks about some tech details, see the question bellow first.
I need to write a wrapper program in C/C++ for an existing program. I know we need to use exec/fork/system and pass through the parameters then return the result of the program.
The question is, how to ensure that both the invoker program(that invoke the wrapper) and the wrapped program work exactly like before (ignore timing differences). There maybe subtle things like environment parameters to deal with. fork/system/exec, which to use? Are they enough? Are there other factors to consider?
Let's say you have the following original program:
foo.sh
#!/bin/bash
echo "Called with: ${#}"
exit 23
Make it executable:
$ chmod +x foo.sh
Now the wrapper in C:
wrapper.c
#include <errno.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(int argc, char* argv[]) {
printf("Executing wrapper code\n");
/* do something ... */
printf("Executing original program\n");
if(execv("./foo.sh", argv) == -1) {
printf("Failed to execute original program: %s\n", strerror(errno));
return -1;
}
}
Run it:
$ gcc wrapper.c
$ ./a.out --foo -b "ar"
Executing wrapper code
Executing original program
Called with: --foo -b ar
$ echo $?
23
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
This is my code:
/* backtrace_foo1.c */
#include <execinfo.h>
#include <stdio.h>
#include <stdlib.h>
#define BACKTRACE() \
do {\
void *array[20];\
size_t size;\
char **strings;\
size_t i;\
size = backtrace(array, 20);\
strings = backtrace_symbols(array, size);\
for (i = 0; i < size; i++) {\
printf ("%s\n", strings[i]);\
}\
free (strings);\
} while(0)
void func1()
{
BACKTRACE();
}
void func()
{
func1();
}
int main(int argc, char **argv)
{
func();
return 0;
}
I compiled it by gcc -g -rdynamic and got
./a.out(func1+0x1f) [0x400905]
./a.out(func+0xe) [0x40097a]
./a.out(main+0x19) [0x400996]
/lib64/libc.so.6(__libc_start_main+0xfd) [0x318ae1ecdd]
./a.out() [0x4007f9]
Then i use addr2line -e ./a.out -f 0x4007f9, i got
_start
??:0
This is my platform
gcc version 5.3.0 (GCC)
Linux 3.10.0_1-0-0-8
I shouldn't really answer this, since you don't really have a question or a stated problem. But sometimes I'm feeling nice...
While the code you write will start execution with the main function, the actual starting point is somewhere before that. There is startup code that will initialize the stdio system (stdin, stdout etc.) and initialize other things. This startup code then calls your main function like any other function.
The "problem" is that the startup code is not really part of your code, it's often a precompiled object file that the frontend program links your program with. And that object file probably doesn't have any kind of debug information, so you can't get any location information about it.
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 6 years ago.
Improve this question
Often during programming contests I forget which library contains which function. Hence I require some C code which can print the available functions with a specific library. eg. usage:
showAvailFunctions("stdlib.h")
and it would print all the available functions with stdlib.h library
Create a C program file with the include directive for the include file you want to see.
For instance:
#include <stdlib.h>
Compile with Preprocessor output to generate a file, usually a file with an extension of .i and you will have the complete contents of the include file.
For Visual Studio, you may need to indicate whether you want to keep the comments or not.
The output file should appear in your working directory.
A more involved example of an approach is as follows. This is a C source text file which does a series of includes with special markers to show what is where.
The program at the bottom of the source file is a simple filter program which reads the C Preprocessor file generated and removes most of the clutter such as blank lines or those "#line " lines of output which specify a line number and the file it came from.
You will need to add whatever include files you want to see. Then compile it twice, once with C Preprocessor output enabled to generate a file containing the C Preprocessor output and once with C Preprocessor output disabled to generate an actual executable file. Your C compiler may provide options to do both steps in a single compile. I could not see how to do that with Visual Studio 2013.
Here is an example source file. I expect you may need to tailor this for your compiler and development environment. This compiles and generates output with Visual Studio 2013. I created a simple .bat file which runs this application from the command line and redirect STDOUT to a text file that contains the filtered C Preprocessor output.
#define MAKE_SEP_STRING "<!-- #$%^&*()_+-=qwrtv -->"
#define MAKE_SEP_STRING_END "<!--END #$%^&*()_+-=qwrtv -->"
#define MAKE_SEP_BEGIN(x) static const char X_##x [] = MAKE_SEP_STRING #x;
#define MAKE_SEP_END
MAKE_SEP_BEGIN(stdio);
#include <stdio.h>
MAKE_SEP_BEGIN(stdlib);
#include <stdlib.h>
MAKE_SEP_END
#include <string.h>
int main(int argc, char* argv[])
{
if (argc < 2) {
printf("output file must be specified.\n");
return 1;
}
else {
char *sep = MAKE_SEP_STRING_END; // if we want to determine where each file begins or ends.
FILE *pFile;
fopen_s(&pFile, argv[1], "r");
if (pFile) {
char hugeBuffer[4096];
// read through the C Preprocessor output file and eliminate empty lines.
// there can be a lot of empty lines.
while (fgets(hugeBuffer, 4000, pFile)) {
if (strlen(hugeBuffer) > 5) {
// discard all those tons of #line n text lines generated by the Preprocessor
if (strncmp(hugeBuffer, "#line ", 6) == 0) continue;
if (strcmp(hugeBuffer, sep) == 0)
{
break;
}
printf("%s\n", hugeBuffer);
}
}
fclose(pFile);
}
}
return 0;
}
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I am using Mac OSX 10.8.4 and programming in C. I trying to use openmp and I am compiling with gcc-mp-4.7. I am working in bash. Currently I have an executable (I will call executable1 in the program) which I am trying to run in parallel by using a system call inside of an openmp parallel for loop. The example code is as follows:
my_omp.c
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <omp.h>
void main() {
int n = 100;
double var1 = 65.4;
char place[100] = "/under/a/rock";
double var2 = 4.5e4;
double var3;
char program[200];
int i;
#pragma omp parallel for private(program,var3)
for (i=0; i<=n; i++) {
var3 = var1*pow(var2,i);
sprintf(program,"./executable1 %.15e %s %.15e %d", var1, place, var2, var3, i);
printf("%s \n", program);
system(program);
}
}
I compile the program using gcc-mp-4.7 -fopenmp my_omp.c, then run the newly compiled executable, (differently named than exectuable1).
What seems to happen is that 8 (which I believe is the number of "cpus" openmp thinks I have) of the print statements will appear in the stdout (terminal) and then it will run only a single call of the executable1, then when it finishes it prints out another of the printf program lines, then runs another executable1 until it finishes the for loop (I know this because executable1 is extremely verbose, and it would be obvious is two where running as numbers printed to stdout would be out of synch and appearing in at multiples).
So it seems maybe that the printf is running in parallel, but for some reason the system() command is not? Does anyone have any ideas?
Thanks for any help you can offer.
UPDATE:
I have gotten this exact code to run properly on a lunix distribution with a different compiler, I will look into finding a better compiler to use in Mac OSX and see if that works.
The system(3) library call in OS X is implemented using a global mutex lock - see the system.c file in the source code of OS X's C library:
#if __DARWIN_UNIX03
pthread_mutex_lock(&__systemfn_mutex);
#endif /* __DARWIN_UNIX03 */
...
#if __DARWIN_UNIX03
pthread_mutex_unlock(&__systemfn_mutex);
#endif /* __DARWIN_UNIX03 */
Therefore when one thread calls into system(3), all other threads have to wait for the first call to finish, resulting in serialised execution.