Can a program be written without main() function?
I have written this code and saved a filename as withoutmain.c
and getting an error as
undefined reference to 'WinMain#16'"
My code
#include<stdio.h>
#include<windows.h>
extern void _exit(register int code);
_start(){
int retval;
retval=myFunc();
_exit(retval);
}
int myFunc(void){
printf("Hiii Pratishtha");
return 0;
}
Please provide me the solution of this problem and also the proper memory construction of code and what is happening at the compiler end of this program.
Thank you!
Can a program be written without main() function?
Yes there can be a C program without a main function.
I would suggest two solutions.......
1) Using a macro that defines main
#include<stdio.h>
#include<windows.h>
#define _start main
extern void _exit(register int code);
int myFunc(void){
printf("Hiii Pratishtha");
return 0;
}
int _start(){
int retval;
retval=myFunc();
_exit(retval);
}
2) Using Entry Point (Assuming you are using visual studio)
To set this linker option in the Visual Studio development environment
/ENTRY:function
A function that specifies a user-defined starting address for an .exe file or DLL.
Open the project's Property Pages dialog box. For details, see
Setting Visual C++ Project Properties.
LClick the Linker folder.
Click the Advanced property page.
Modify the Entry Point property.
OR
if you are using gcc then
-Wl,-e_start
the -Wl,... thing passes arguments to the linker, and the linker takes a -e argument to set the entry function
Related
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
I have a 218KB .dll and a 596KB .so file, both with identical names. I want to link to the .dll to avoid the "unresolved external symbol" error that the linker returns, but I can't find a way to link to the DLL file.
According to this Pelles C forum topic, I need to use the .def file to create a .lib... but I don't have a .def file. This forum topic shows how to use polink to create a .lib from the command line, so I ran polink /? to get some more options. I noticed a /MAKEDEF option, but running this with both the .dll and the .so gives a "No library file specified" fatal error.
I have been trying to do this for three hours, and am out of ideas. I have got to the point where my web searches turn up my own help-requests. There must be a way to do this... How can I link to a .dll?
With information found in the header #include and your details, here is a way to replace the missing function by calling them dynamically from your software.
1- the following prototype is in #include :
typedef float (* XPLMFlightLoop_f)(float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon);
2- some const that you can fill as needed:
const char *sDllPathName = "<Your XPLM_API DLL>.dll";
const char *sXPLMRegisterFlightLoopCallbackName = "XPLMRegisterFlightLoopCallback";
In order to confirm the sXPLMRegisterFlightLoopCallbackName, you can
use the freeware Dependency Walker and check name and format of
the exported functions.
3- declare the prototype of the external function:
Be aware to the calling convention __cdecl or __stdcall
In the current case, the keyword XPLM_API is defined in the XPLMDefs.h as follow:
#define XPLM_API __declspec(dllexport) // meaning __cdecl calling convention
typedef void (__cdecl *XPLMRegisterFlightLoopCallback_PROC)(XPLMFlightLoop_f, float, void *);
4- clone the function to call it in your software:
#include <windows.h>
void XPLMRegisterFlightLoopCallback(XPLMFlightLoop_f inFlightLoop, float inInterval, void * inRefcon)
{
HINSTANCE hInstDLL;
XPLMRegisterFlightLoopCallback_PROC pMyDynamicProc = NULL;
// Load your DLL in memory
hInstDLL = LoadLibrary(sDllPathName);
if (hInstDLL!=NULL)
{
// Search for the XPLM Function
pMyDynamicProc = (XPLMRegisterFlightLoopCallback_PROC) GetProcAddress(hInstDLL, sXPLMRegisterFlightLoopCallbackName);
if (pMyDynamicProc != NULL)
{
// Call the XPLM Function with the orignal parameter
(pMyDynamicProc)(inFlightLoop,inInterval,inRefcon);
return;
}
}
// Do something when DLL is missing or function not found
}
5- just add your described call:
...
XPLMRegisterFlightLoopCallback(callbackfunction, 0, NULL);
...
I am trying to simply run two ncurse windows using pthread. The code i have written is as follows:
#include<stdio.h>
#include<pthread.h>
#include<ncurses.h>
#include<sys/ioctl.h>
#include<string.h>
#include<unistd.h>
struct winsize w;
WINDOW *win1,*win2;
void createWin1(void){
while(1){
char buffer[1024];
win1=newwin(0,0,40,50);
box(win1,0,0);
wrefresh(win1);
sleep(1);
}
}
void createWin2(void){
while(1){
win2=newwin(40,50,40,60);
box(win2,0,0);
wrefresh(win2);
sleep(1);
}
}
void main()
{ initscr();
noecho();
cbreak();
start_color();
use_default_colors();
init_pair(1,COLOR_WHITE, -1);
pthread_t p1,p2;
pthread_create(&p1,NULL,(void *)createWin1,NULL);
pthread_create(&p2,NULL,(void *)createWin2,NULL);
pthread_join(p1,NULL);
pthread_join(p2,NULL);
}
Now the problem is I cant run two windows in parallel .This will show unexpected output. Can anyone please help me to find out the issue in my code.
The approach used in the sample code cannot work reliably because curses uses static/global variables. You can either setup mutexes around the ncurses calls (to ensure that input or output from one thread is separate from the others), or compile (there are few packages) the version with rudimentary threading support as a starting point.
In the ncurses FAQ, start with Why does (fill in the blank) happen when I use two threads?
i think you have to include #include ncurses.h in your source code ?
the declaration struct winsize w; seems to create an incomplete type
the variable flag is not declared in the scope of the function createWin1()
try to paste the entire code if possible
i've an error of including panel.h
i've a problem with my opensuse right now, i found some people with the same problem so i'm looking for that, i mean about including panel.h
error 'row' was not declared in this scope
in win1=newwin(w.ws_row-row
I'm trying to find the paramiters you used for the variable w "ws_row-row" is it correct, try to search the content of WINDOW struct ??
i think you have to define newwin correctely with good values
WINDOW * win = newwin(nlines, ncols, y0, x0);
http://hughm.cs.ukzn.ac.za/~murrellh/os/notes/ncurses.html#window
still four errors in my side
main has to return a value , i declared it int main, and i return zero, the compiler complain about that
there is some errors about conversion in pthread_create
you function have to be declared void* createWin1(void*)
and not void createWin1(void)
do you have any compilation errors in your side or not ?
i'm trying to help you i'm not a specialist about ncurses
now the compilation is ok but i have linker errors
undefined reference to newwin .....
it's a library problem, think we are not far from: https://github.com/mariostg/nffm/issues/2
i compiled with g++ -pthread test.c for now, i w'll look again tomorow
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.
I'm new to this site & not highly experienced in C,so pl pardon any mistakes I might commit unknowingly.
Ok,so I've got two files in C, one containing a function, & other one using that function.I think I'll need to create a header file for it,but I somehow cannot make it & need help.
here's file 1 :
#include<stdio.h>
int tempc=25,tempf;
int c2f(int c);
void main()
{
tempf=c2f(tempc);
printf("Celsius = %d,Farenheit=%d \n",tempc,tempf);
}
int c2f(int c)
{
int f;
f=9*c/5 + 32;
return f;
}
Here's file 2:
#include<stdio.h>
int tempc=25,tempf;
extern int c2f(int c);
void extern show(void);
void main()
{
tempf=c2f(tempc);
show();
}
The main question comes here. you might as well be thinking about the show function.
Actually, I'm asked to convert f1 into .asm file (using tcc -S f1.c) then add a module for show fn using assembly language, create .obj file of the .asm file, & with .obj file of f2, I've to put them in project & then build all to create .exe file.But I believe if I can simply run the program using 2 files as .c(ie with header part solved) I can do the rest.
One last question is, instead of creating header I'm wanting to do above, is it possible to keep these two files as they are, & create a header file-> make it .obj & add it to the project & build ?
A Sincere thanks to whoever tries to help.
A header file is meant to be used as a mechanism to "expose" functions to other C modules. For instance, you define a c2f() function in c2f.c and then create a prototype (essentially just a placeholder) in c2f.h. The prototype in c2f.h would look like the following:
int c2f(int c); /* Note the semicolon */
It shouldn't matter if the implementation of c2f() is in an assembly or c file. The header file simply allows C modules to make calls to c2f(). This is because you are providing the linker information to find the actual implementation of a function. The linker will then match all calls to that function to the actual address of the implementation. So, to use c2f just reference c2f.h in the file that is using it:
/* main.c */
#include "c2f.h"
...
You need to put c2f in a header and source files as such:
c2f.h:
int c2f(int c);
c2f.c:
int c2f(int c) {
return 9*c/5 + 32;
}
then compile that so you have a c2f.o file, include c2f.h in your two main() files that use it and linktheir compilation to the c2f.o file.