So I am trying to convert a C program that uses standard libraries to a standalone application (it is an assignment). This involves writing simple functions for printf, malloc, free and etc. While working on this, I came across a problem of converting fflush(stdout) because stdout is included in stdio.h and must be replaced with something else.
Naturally, I looked at the macro in stdio.h which looked like:
#define stdout (__iob[1])
I used this macro declaration in my C file, removed the stdio.h header, and tried to compile it, but it gave an error __iob is undeclared. When I looked at the source file more in detail, there was a data structure:
extern struct __file *__iob[];
With this included, when compiled, it gives another error below and I am not sure what to make of this:
/tmp/ccOTmFBR.o: In function `func1':
program.c:(.text+0x46): undefined reference to `__iob'
/tmp/ccOTmFBR.o: In function `func2':
program.c:(.text+0xff): undefined reference to `__iob'
collect2: error: ld returned 1 exit status
make: *** [all] Error 1
My question is basically what would be the simplest way to replace fflush(stdout) in a C program without using the stdio.h.
Related
I wrote a header file containing function prototypes and imported into the main.c file! all though it compiles and runs i get a warning "implicit declaration of function" for only 1 function! with no other warnings related to the other functions which have prototypes declared in the header file! What is the reason for this?
Probably you are using a function that was not declared. Please refer to link
If you call a function without declaring it, the use of the function becomes it's (implicit) declaration and implicit declarations are actually errors in C. Your program only displays it as a warning because your gcc compiler chooses to.
Since all of your other functions work with the given prototypes, I would suggest to review your function declaration and ensure no typos. If you post your code... I will update my answer with a more appropriate response.
To give a clearer answer I would need to see the code, but for a start, you should never include a .c file. for example, in main.c you should include your header using #include, and then if you have a library you are using, you should include the header file in that as well, but not the main.
It may also be that your function is of the incorrect type, or has a different type than specified in the prototype.
I am trying to compile old project, but I got an error. That project implements function dprintf, which is some kind of a printf function. However when I tried to compile that project today I found out that dprintf is already defined in stdio.h. So my question is - how to hide the standard dprintf function, because now I'm constantly getting an error like this:
ntreg.c:82: error: conflicting types for 'dprintf'
/usr/include/stdio.h:397: note: previous declaration of 'dprintf' was here
ntreg.c:93: error: conflicting types for 'dprintf'
/usr/include/stdio.h:397: note: previous declaration of 'dprintf' was here
dprintf() is not defined by the Standard.
If you configure your compiler for Standard C, the function should no longer be exposed
gcc -std=c99 -pedantic ...
Just rename your implementation to something else like
int dprintf(... parameters ...)
to
int not_stdio_dprintf(... parameters ...)
and then wherever you use it add
#define dprintf not_stdio_dprintf
When I create a simple C program in Visual Studio 2010,
http://debugmode.net/2012/02/06/how-to-write-and-run-a-c-program-in-visual-studio-2010/
I remove the "#include < stdio.h > ",
My program still runs successfully, I could not understand how is it possible?
Any help is appreciated.
Regards,
The stdio.h header isn't strictly required unless you use functions declared in it, such as the following:
http://www.acm.uiuc.edu/webmonkeys/book/c_guide/2.12.html
Further looking at the code I believe the default behaviour when you don't have a prototype is to assume an int return type and to derive the types of parameters from the types of arguments which will work in this particular case. But it's generally a bad practice and should be avoided.
If that passed through the compiler / linker without any warnings you may want to check your environment settings. It's easy to forget to include an header and it can cause a lot of unintended and hard to track down side effects if you don't notice it.
The primary purpose of including standard header files is to include the declarations of standard functions into your source file.
However, the original standard C language (C89/90) did not require functions to be declared before they are called (aside from variadic functions, which have to be pre-declared with prototype to avoid undefined behavior). For this reason, as long as we are talking about non-variadic function calls, it is perfectly possible to write a correct program without pre-declaring standard functions, i.e. without including standard header files.
For example, calling strcmp function with two char * arguments is perfectly legal in C89/90 without pre-declaring strcmp. Meanwhile, printf has to be pre-declared with prototype, if you want your program to remain a valid C program with defined behavior.
This header file provides prototypes for a number of common functions and macros.
If you don't call any of those functions or macros, then you don't need it. If you do call them, it can still work as long as you are linking with the right libraries. But you could get some compiler errors or warnings if the compiler doesn't have those definitions.
#include < stdio.h >
It is a header file known as standard input output file. The input,output funcation are written in this file. funcations like printf,scanf etc.
Refere this http://computer.howstuffworks.com/c2.htm
I am following the C programming tutorial at http://www.cprogramming.com/tutorial/c/lesson10.html. This particular tutorial teaches file I/O in C; in particular, the fopen command is discussed. At one point, they give the following example (which I think should print the contents of file test.txt):
FILE *fp;
fp=fopen("c:\\test.txt", "w");
fprintf(fp, "Testing...\n");
So, I made a text file called test.txt and saved it in my current, working directory (C:\cygwin\home\Andrew\cprogramming). Then I created a c file in this same directory, and it contains the following code:
#include <stdio.h>
int main()
{
FILE *fp;
fp=open("test.txt","w");
fprintf(fp,"Testing...\n");
}
When I compile this c file (which I've called helloworld2.c) using gcc, I get the following messages:
helloworld2.c: In function `main':
helloworld2.c:40: warning: assignment makes pointer from integer without a cast
Then when I try to run the executable, I get:
Segmentation fault (core dumped)
Do you have any ideas about what I should try next?
Thank you very much for your time.
This is because you use open instead of fopen. Open is from the POSIX standard and returns an (integer) handle; fopen returns the memory address of a FILE structure. You cannot use both in an interchangeable way. As it stands, your code implicitly casts the received integer (likely 4) to a FILE* pointer, making it point to the memory address 4. This segfaults your program when fprintf attempts to access it.
fopen is cross-platform, but open is POSIX-only. You may want to stick to fopen for now.
fopen() returns a pointer to a FILE object while open() returns a file descriptor which is a plain int.
Unless you need low-level functions it's usually better to work with fopen and FILE objects.
I'm guessing this was just an unfortunate typo - open() instead of fopen() - which just happens to work well enough to build a final executable (rather than a deliberate attempt to use open())...
You see warning: assignment makes pointer from integer without a cast because there is no "prototype" - a declaration of the argument and return types - for open() in <stdio.h>.
In the absence of such a prototype, the compiler assumes that such a function exists and returns an int, which your code assigns to the pointer variable fp.
It does in fact link successfully because there is a function called open() in the C library, but it does something different (as others have mentioned). But if (for example) you'd written fpen() instead, things would have gone more obviously wrong - it would have failed at the link stage, as there is no library function of that name.
If you compile with more warnings enabled - e.g. -Wall for GCC - you'll get some more helpful errors:
$ gcc -Wall -o helloworld2 helloworld2.c
helloworld2.c: In function 'main':
helloworld2.c:6: warning: implicit declaration of function 'open'
helloworld2.c:6: warning: assignment makes pointer from integer without a cast
helloworld2.c:8: warning: control reaches end of non-void function
$
The warning: implicit declaration of function 'open' tells you that there is a mismatch between the headers you've included, and the function you're trying to use.
I'm trying to build a wrapper library with VC++'s compiler.
ErlDriver.c
#define __WIN32__
#define DLL_EXPORT __declspec(dllexport)
#include "erl_driver.h"
DLL_EXPORT int _driver_output(ErlDrvPort port, char *buf, int len) {
return driver_output(port, buf, len);
}
build.bat
cl /I%ERL_DRIVER_H% /LD /MD ErlDriver.c
When I attempt to build this, I get the following linker error:
ErlDriver.obj : error LNK2019: unresolved external symbol _WinDynDriverCallbacks referenced in function __driver_output
erl_win_dyn_driver.h (included in erl_driver.h)
typedef struct {
WDD_FTYPE(driver_output) *driver_output;
// a ton more of those
} TWinDynDriverCallbacks;
extern TWinDynDriverCallbacks WinDynDriverCallbacks;
#define driver_output (WinDynDriverCallbacks.driver_output)
So, as you can see, WinDynDriverCallbacks is defined declared.
What could be causing the linker error, then?
No, it's not defined (at least in what you quoted). It's declared. The "extern" keyword means "the definition for this symbol appears in another compilation unit (source file)." You need to be linking with the object file (or library) produced from compiling the source file that defines that symbol.
There is a subtle difference between "declaring" something and "defining" it in C or C++. When you declare it, it tells the compiler that a certain symbol will be defined somewhere else - this can allow the code to use that symbol without needing to see the actual definition. You still have to define the symbol somewhere in the code that is linked in, or else you will get the error message you are seeing.
For example, this is a declaration of the symbol WinDynDriverCallbacks:
extern TWinDynDriverCallbacks WinDynDriverCallbacks;
Your code has this declaration - it allows the code that uses the symbol to successfully compile (but not link).
You need to add a definition somewhere:
TWinDynDriverCallbacks WinDynDriverCallbacks;
The definition must go into a source code file somewhere (not generally in a header file). This tells the compiler to allocate space in the object code for that object and allows the program to link successfully.
I got a very similar problem building a NIF on Windows. Unresolved external symbol _WinDynNifCallbacks. Turns out this is defined by the ERL_NIF_INIT macro and in my case the entire macro needed to be enclosed in a extern C block.
ie this failed
extern "C" ERL_NIF_INIT(...)
while this succeeded
extern "C"
{
ERL_NIF_INIT(...)
}
I strongly suspect this problem is due to the same issue but with the DRIVER_INIT macro for an erlang port driver.
Driver_Init is the main loop that declares "TWinDynDriverCallbacks WinDynDriverCallbacks;" but it's properly declared in the multiple line define for driver_init. You shouldn't need to wrap it in extern "c".
since this thread came up about a million times while trying to setup my barebones erlang port driver i will say this here. I am working out of Joe Armstrong's programming erlang book, chapter 12 interfacing techniques. Using erl5.9 and vs2010.
The code in the book had a omission and a error in example1_lib.c. Though the error is most likely due to the age of the book versus erlang version changes.
Needed to set (#define WIN32) at the very top of example1_lib.c otherwise erlang defaulted to all the Linux options.
Second needed to change (int bufflen) to (ErlDrvSizeT bufflen) in example_drv_output.
After that it built clean.