C Program, linker error - c

#include <stdio.h>
int main(int argc, char *argv[])
{
print("Merry Christmas and happy holidays!");
return 0;
}
Can someone please run this on your system and check back why?
It says, linker error print is not defined.

There's no print function in standard C. The function you are looking for is printf (f here is short for formatted.
printf("Merry Christmas and happy holidays!");

It is not print, it is called printf function. There is nothing call print in C .standard

linker errors are due to the call of functions that are not defined or due to wrong way of call of a function.
In your program function print() does not exist anywhere as a user defined function nor does it exist in the header 'stdio.h' that you included.
To print a line in C you need to use printf() statement and not print() as in your program.

Related

How do calls to the execvp system call work?

I was doing a research into the contents of another StackOverflow question and I thought it was a good time to brush up my knowledge of unix system calls.
While experimenting with execvp (WITHOUT fork on purpose) I ran into something that confuses me
I wrote 4 test programs
Program 1
#include <stdio.h>
int main() {
//printf("Doge\n");
execvp("ls");
printf("Foo\n");
return 0;
}
The program works as expected, the contents of the directory are printed and the Foo print statement is not
Program 2
However when I uncomment the first print statement and have the program be this
#include <stdio.h>
int main() {
printf("Doge\n");
execvp("ls");
printf("Foo\n");
return 0;
}
execvp returns a -1 and both print statements are issued. why?
Program 3
I vaguely remember having to use unistd.h when experimenting with unix system calls from college.
So I included it, but not execvp has a different signature and it needed some more args than just the name of the program. So I did this
#include <stdio.h>
#include <unistd.h>
int main() {
printf("Doge\n");
char *const parmList[] = {"ls", NULL};
execvp("ls", parmList);
printf("Foo\n");
return 0;
}
And this works. This has confused me. Why did exec work in the first program?
I also used This as a reference to the system calls.
Finally I wrote
Program 4
#include <stdio.h>
//#include <unistd.h>
int main() {
printf("Doge\n");
char *const parmList[] = {"ls", NULL};
execvp("ls", parmList);
printf("Foo\n");
return 0;
}
Which also works as expected.
Can someone explain what's going on?
With this snippet
#include <stdio.h>
int main() {
execvp("ls");
printf("Foo\n");
return 0;
}
you're invoking undefined behaviour. You're not providing the prototype for execvp which requires an argument list (null terminated) as a second parameter.
Using gcc without any warning option silently uses execvp as implicitly declared, and doesn't check parameters. It just calls the function. The function then looks for a second parameter and encounters... whatever is left of the call stack (or registers, depending on call conventions), that's why a previous printf call can change the behaviour.
Using gcc -Wall gives the following warning:
test.c:5:9: warning: implicit declaration of function 'execvp' [-Wimplicit-function-declaration]
execvp("ls");
Including the proper include (#include <unistd.h>) leads to:
test.c:6:9: error: too few arguments to function 'execvp'
execvp("ls");
^~~~~~
That's why you've got strange behaviour. Don't look further. Use execvp with 2 arguments, period. In your case "Program 3" is the way to go, and always set warning level to the maximum, if possible (gcc and clang: -Wall -Wextra -pedantic -Werror)

Redefining main to another name

In C90, can I redefine main and give it another name, and possibly add extra parameters using #define?
Have this in a header file for example:
#include <stdio.h>
#include <stdlib.h>
#define main( void ) new_main( void )
int new_main( void );
The header doesn't show any errors when compiling.
When I try compiling it with the main C file, however, I keep getting an error
In function '_start': Undefined reference to 'main'
No, you cannot do that, because it would be against language and OS standards. The name main and its arguments argc, argv and environ constitute a part of system loader calling conventions.
A bit simplifying explanation (no ABI level, just API level) ensues. When your program has been loaded into memory and is about to start, the loader needs to know which function to call as an entrypoint, and how to pass its environment to it. If it was be possible to change the name of main and/or its parameter list, it would have been needed to communicate details of new calling interface back to the loader. And there is no convenient way to do it (apart from writing your own executable loader).
In function '_start': Undefined reference to 'main'
Here you can see an implementation detail of Linux/POISX ELF loader interface. The compiler adds function _start to your program behind the scenes, which is an actual program entrypoint. _start is tasked to do extra initialization steps common to most programs that use LibC. It is _start that later calls your main. Theoretically, you could write a program that has its own function called _start and no main and it would be fine. It is not trivial as you will have to make sure that the default _start code is no longer being attached to your program (no double definitions), but it is doable. And no, you cannot choose other name than _start for the same reasons.
The presence of #define main new_main within a compilation unit will not affect the name of the function the implementation will call on program startup. The implementation is going to call a function called main regardless of any macros you define.
If you are going to use a #define like that to prevent the primary declaration of main() from producing a function by that name, you'll need to include a definition of main() somewhere else; that alternate version could then invoke the original. For example, if the original definition didn't use its arguments, and if the program exits only by returning from main() [as opposed to using exit()] you might put #define main new_main within a header file used by the primary definition of main, and then in another file do something like:
#include <stdio.h>
#include <conio.h> // For getch() function.
int main(void)
{
int result = main();
printf("\nExit code was %d. Strike any key.\n", result);
getch();
return result;
}
In most cases, it would be better to add any such code within the ordinary "main" function, but this approach can be useful in cases where the file containing main is produced by code generation tools on every build, or for some other reason cannot be modified to include such code.
No you cannot (as Grigory said).
You can however, immediate call your proxy main,
int
your_new_main(int argc, char* argv[], char* envp[]) {
... //your stuff goes here
}
//just place this in an include file, and only include in main...
int
main( int argc, char* argv[], char* envp[])
{
int result = your_new_main(argc, argv);
return result;
}
As far as whether envp is supported everywhere?
Is char *envp[] as a third argument to main() portable
Assuming you're using gcc passing -nostdlib to your program, and then set a new entry, by passing this to gcc which passing it to the linker, -Wl,-enew_main. Doing this won't give you access to any of the nice features that the C runtime does before calling your main, and you'd have to do it yourself.
You can look at resources about what happens before main is called.
What Happens Before main

Confusion about output of program

I am new to C programming and I am currently learning loops. In the below program,
#include<stdio.h>
main()
{
int i;
for(i=1;i++<=5;printf("%d",i));
}
i tried to compile in dev c++ compiler but it is giving error "[Error] ld returned 1 exit status"
You need to include the <stdio.h> header, and also, main needs a return type (int) and a return value. Changing the program to this will make it compile (at least it did using GCC) and run:
#include <stdio.h>
int main(int argc, char *argv[])
{
int i;
for(i=1;i++<=5;printf("%d",i));
return 0;
}
The quotes you used in the ā€œ%dā€ are illegal too, use normal quotes: "%d".
Apart from that, doing the printf inside the loop head might be legal, but it's pretty bad style. Usually in a for-loop you would have have initialization;condition;increment(or decrement or w/e) in the head, and do side-effects in the body of the statement.
I would try writing the for loop as:
for(i=1;i < 6;i++) { printf(ā€œ%dā€,i); }
I have run this program manually on my notebook and i got Output 23456
Then i run this on Dev c++ and it is giving the same output 23456 without any error and i have just copied and pasted from ur question dun know why its showing error on ur runtime may be u have not saved it as C file

Old version of C syntax differences?

For a very specific project, I need to write a 16-bit program in C and I'm using Microsoft QuickC in MS-DOS to write this program. Now I'm pretty sure the syntax of my program is correct but the program just won't compile and it thinks I have syntax errors. Is this because C-compilers in MS-DOS using an older version of C with different syntax?
#include<stdio.h>
main()
{
printf("Hello World!");
}
Not even that simple hello world program will compile and run.
you should define main as int
so change your code to :
int main() { // define main as an int returning function
// your code
return 0; // Also make sure you have return statement in main
}
and it will compile
Here is what it says in the standards:
1 The function called at program startup is named main. The implementation declares no prototype for this function. It shall be defined with a return type of int :
int main(void) { /* ... */ }
Edit:
Ok from your comments .. you are now getting this error:
C1024: cannot open include file 'stdio.h'
Here is a cause and solution from microsoft:
http://support.microsoft.com/kb/97809
You can't omit the type of the function main, or any other C function, for that matter. So, you want
void main() { ... }
or
int main(int argc, char **argv) { ... }
although with the latter one the compiler will usually require you to return a value.

Use of exit() function

I want to know how and when can I use the exit() function like the program in my book:
#include<stdio.h>
void main()
{
int goals;
printf("enter number of goals scored");
scanf("%d",&goals);
if(goals<=5)
goto sos;
else
{
printf("hehe");
exit( );
}
sos:
printf("to err is human");
}
When I run it, it shows ERROR: call to undefined function exit().
Also, I want to know how I can create an option to close the window in which the program runs? For example, I made a menu-driven program which had several options and one of them was "exit the menu". How can I make this exit the program (i.e. close the window)?
Try using exit(0); instead. The exit function expects an integer parameter. And don't forget to #include <stdlib.h>.
The exit function is declared in the stdlib header, so you need to have
#include <stdlib.h>
at the top of your program to be able to use exit.
Note also that exit takes an integer argument, so you can't call it like exit(), you have to call as exit(0) or exit(42). 0 usually means your program completed successfully, and nonzero values are used as error codes.
There are also predefined macros EXIT_SUCCESS and EXIT_FAILURE, e.g. exit(EXIT_SUCCESS);
exit(int code); is declared in stdlib.h so you need an
#include <stdlib.h>
Also:
- You have no parameter for the exit(), it requires an int so provide one.
- Burn this book, it uses goto which is (for everyone but linux kernel hackers) bad, very, very, VERY bad.
Edit:
Oh, and
void main()
is bad, too, it's:
int main(int argc, char *argv[])
Try man exit.
Oh, and:
#include <stdlib.h>
int main(void) {
/* ... */
if (error_occured) {
return (EXIT_FAILURE);
}
/* ... */
return (EXIT_SUCCESS);
}
The exit() function is a type of function with a return type without an argument. It's defined by the stdlib header file.
You need to use ( exit(0) or exit(EXIT_SUCCESS)) or (exit(non-zero) or exit(EXIT_FAILURE) ).
The following example shows the usage of the exit() function.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
printf("Start of the program....\n");
printf("Exiting the program....\n");
exit(0);
printf("End of the program....\n");
return 0;
}
Output
Start of the program....
Exiting the program....
You must add a line with #include <stdlib.h> to include that header file
and exit must return a value so assign some integer in exit(any_integer).
In addition to return an exit code to parent process -
In UNIX, an important aspect that I think has been left out is, that exit() at first calls (in reverse order) all those functions, which were registered by atexit() call.
Please refer to SUSv4 for details.
on unix like operating systems exit belongs to group of system calls. system calls are special calls which enable user code (your code) to call kernel code. so exit call makes some OS specific clean-up actions before returning control to OS, it terminates the program.
#include <stdlib.h>
// example 1
int main(int argc, char *argv){
exit(EXIT_SUCCESS);
}
// example 2
int main(int argc, char *argv){
return 0;
}
Some compilers will give you the same opcode from both of these examples but some won't. For example opcode from first function will not include any kind of stack positioning opcode which will be included in the second example like for any other function. You could compile both examples and disassemble them and you will see the difference.
You can use exit from any part of your code and be sure that process terminates. Don't forget to include integer parameter.
Write header file #include<process.h> and replace exit(); with exit(0);. This will definitely work in Turbo C; for other compilers I don't know.
Bad programming practice. Using a goto function is a complete no no in C programming.
Also include header file stdlib.h by writing #include <iostream.h>for using exit() function. Also remember that exit() function takes an integer argument . Use exit(0) if the program completed successfully and exit(-1) or exit function with any non zero value as the argument if the program has error.
Include stdlib.h in your header, and then call abort(); in any place you want to exit your program. Like this:
switch(varName)
{
case 1:
blah blah;
case 2:
blah blah;
case 3:
abort();
}
When the user enters the switch accepts this and give it to the case 3 where you call the abort function. It will exit your screen immediately after hitting enter key.
Use process.h instead of stdlib and iostream... It will work 100%.

Resources