I found this question very interesting: How to force compilation error if function return value is not checked?
It's about enforcing compilation errors if you do not check the return value. I wrote an answer to that question where you can use gcc extensions like this:
__attribute__ ((warn_unused_result)) int foo (void)
{
return 5;
}
to enforce a warning and the compile with -Werror=unused-result to make the compiler generate an error if you don't use the return value somehow.
Now I would like to create wrapper functions to the regular standard functions. An idea is to rename them like this:
__attribute__ ((warn_unused_result)) realloc_wrapper(void *ptr, size_t new_size)
{
return realloc(ptr, new_size);
}
But the problem is that this forces me to use a different name, which would cause a lot of search and replace. Granted, this can be done automatically, but still. Preferably, I would like to be able to create a header that I can use instead of a standard C header for any program. One use case is when debugging a big program. Then this would instantly point me to potential causes of bugs.
TL;DR
So in short, I want to be able to take this program:
#include <stdlib.h>
int main(void)
{
char *ptr;
realloc(ptr, 42);
}
and change it to:
// Replaced stdlib with a custom header
#include <mystdlib.h>
int main(void)
{
char *ptr;
realloc(ptr, 42);
}
and then the line with realloc should generate a warning.
I might add that I'm ok with a solution that isn't 100% perfect. The intended use is for debugging and not production code.
EDIT:
I just noticed that realloc was a bad choice, since it seems to already have this declaration by default, but I used PSkocik and made it work for fgets.
A straightforward solution would be to shadow the function with an identically named macro. (I'll use puts as an example, because, as you've mentioned, realloc is already usually declared with warn_unused_result)
/*begin your header:*/
#include <stdio.h>
__attribute ((__warn_unused_result__)) static inline
int puts_wrapper(char const*X)
{
return (puts)(X);
}
#define puts(X) puts_wrapper(X)
/*end your header*/
int main(void) { puts("hello, world"); }
(The parentheses around puts aren't necessary but they allow you to move the define before the puts_wrapper definition if you wanted to.)
Alternatively, you could simply redeclare the function with the warn_unused_result attribute added (works on both gcc and clang).
/*begin your header*/
#include <stdio.h>
__attribute ((__warn_unused_result__)) int puts(char const*);
/*end your header*/
int main(void) { puts("hello, world"); }
Related
So I'm new to c and wrote some code but i'm not sure why i'm getting an error when i try to run it.
int GlobalVariable=0;
int main()
{
int LocalVariable=0; //can be used within main()
dis();
printf(GlobalVariable);
return 1;
}
int dis()
{
GlobalVariable=5; //Can be accessed in any functions and made changes to it
}
Here is the prototype of printf function:
int printf(const char * restrict format, ...);
And look what you are typing:
int GlobalVariable=0;
printf(GlobalVariable);
The problem is that you used a function without first telling the compiler about it.
In this case you must provide function prototype as the function definition itself is provided after main
int dis( void ); // function prototype
int main()
{
...
}
int dis() // function definition
{
...
}
Alternatively, you can put the function definition before main(). But usually it would be better to have function prototypes before main() and (usually) even better to put the prototypes in a separate header file - that way it'd be easier to look straight into the main program without being bother about other function details.
I want to be able to reference variable sized array with a global pointer. But what kind of pointer do I use that will work with variable sizes of the array? In the example below, assume N will only be known at runtime (could be an argument for example) so compile time solutions won't work.
What I want to achieve:
main.c
some_sort_of_pointer *x;
main()
{
int N=256; //or N=64 or whatever
char (*LC)[N];
LC=malloc(1024);
x=LC;
memcpy(x[2],"hello world",11);
x[0][176]=123;
dostuff();
}
I'm sure there's an easy obvious way to do this but I can't seem to nail it. My first attempt at asking this was a mess so this time I'm hoping it's clear what I want to achieve.
OS Centos 6.5
compiler GCC 4.8 (using C99)
As at compile time the type to be referenced isn't given, a void pointer might help.
However only storing an untyped reference (what void * in fact is is) is not enough, as it is essential to also know the size of the (VL)array. So the latter also needs to be stored globally, as it can not be pulled from the memory referenced.
An example how this can be achieve is given below:
main.h:
#include <stdlib.h> /* for size_t */
struct VLA_descriptor
{
void * p;
size_t s;
}
extern struct VLA_descriptor vla_descriptor;
foo.h:
void foo(void);
foo.c:
#include "main.h"
#include "foo.h
void foo(void)
{
char (*p)[vla_descriptor.s] = vla_descriptor.p;
/* Do something with the VLA reference p. */
}
main.c:
#include "main.h"
#include "foo.h"
struct VLA_descriptor vla_descriptor = {0};
int main(int argc, char ** argv)
{
size_t s = atoi(argv[1]);
char (*p)[s] = malloc(s);
vla_descriptor.p = p;
vla_descriptor.s = s;
foo();
... /* Free stuff and return. */
}
Error checking had been omitted in this example's code for the sake of readability.
With much thanks to #alk (and everyone else who responded) I think I have the closest I'm going to get to what I'm looking for:
void *LC
int LCS;
int main(int argc, char **argv) {
LCS=256;
LC=malloc(1024)
memcpy(((char(*)[LCS])LC)[2],"hello world",11);
((char(*)[LCS])LC)[0][176]=123;
printf("%d %s\n",((char(*)[LCS])LC)[0][176],&((char(*)[LCS])LC)[2]);
}
((char(*)[LCS])LC) is the equivalent of a what I wanted. It's similar to #alk's idea and does require 2 globals but it means I can use it in functions without having to declare a new variable. I've credited #alk with the answer as what he posted gave me 90% of what I needed.
Though if anyone can reduce ((char(*)[LCS])LC) to a single global, I would be excited to see it :)
I have used the #pragma directive inside functions without error or warning(especially #pragma pack()).But the following code shows the warning incompatible implicit declaration of built-in function 'printf'|:
int main(void)
{
printf("Trial");
}
#include<stdio.h>
Further, here's is an extract from a book I have.The author has bad reviews on SO,especially for his generous use of void main(),but still I feel no author can be that bad to claim the following without reason:
Each of these preprocessor directives begin with a #
symbol. The directives can be placed anywhere in a program but
are most often placed at the beginning of a program, before the
first function definition.
So can you tell me whether it's mandatory to use some preprocessor directives like #include at the top of the program while others like #pragma can be used anywhere in the program?
Edit After OUAH's remark I tried the following, but it doesn't give warning,it gives a big pile of errors.LOL.
int main(void)
{
#include<stdio.h>
printf("Trial");
}
Think of it this way. The content of the included file is simply inserted at the point in the file where the #include directive appears. The resulting code needs to be syntactically correct for the language that you are programming in.
Confider the following file:
int a;
int foo();
int main()
#include "myheader.h"
int foo()
{
return 0;
}
And the file myheader.h contains:
{
return foo();
}
The code that the compiler will see after the preprocessor has processed the #include directive is:
int a;
int foo();
int main()
{
return foo();
}
int foo()
{
return 0;
}
This is valid C syntax. Such use of the #include directive is not recommended, but it gives you an idea of what it means. If the myheader.h file had the following content:
this is some garbage
which is not proper C
Then the resulting code will be:
int a;
int foo();
int main()
this is some garbage
which is not proper C
int foo()
{
return 0;
}
You can use #include at any point in the file. It results in literal inclusion of the content of the included file at that point. The reason you get a undeclared message for printf() in your code is that C requires a function be declared before use, and stdio.h has that declaration. Which is why it needs to be before it's use. And why it cannot be included in main() in the latter example is because on inclusion (expansion), it results in syntactically incorrect C code.
An #include directive can be placed anywhere in a source file, but in C an identifier can usually not be used before it has been declared. That's the reason why you put the #include directive at the begining of your source file.
void foo(void)
{
printf("Hello world\n");
}
extern int printf(const char *, ...); // Error, the declaration should be put
// before the actual call
"#pragma" directive will be ignored by C compiler since it considers the lines with "#" tag as comments. Looks like you are using openmp. The OpenMP compiler considers these(#pragma) as parallel directives. Hope this helps.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char *s;
s = strdup("foo");
printf("%s\n", s);
getchar();
return 0;
}
Looks pretty harmless, doesn't it ?
But my IDE, which is Dev-C++, gives my the following warning:
warning: assignment makes pointer from integer without a cast
The warning disappears if you would change the code like this:
char *s;
s = (char*)strdup("foo");
Can anyone help me explain this?
You're using Dev-C++, but strdup is not part of the C or C++ standard, it's a POSIX function. You need to define the proper (according to your IDE's documentation) preprocessor symbols in order for strdup to be declared by the header file ... this is necessary in order for the header file not to pollute the name space when included into conforming C or C++ source files.
For a simple portable alternative, consider
char* mystrdup(const char* s)
{
char* p = malloc(strlen(s)+1);
if (p) strcpy(p, s);
return p;
}
Or, if you know strdup is actually in the library, you can copy its declaration from string.h into your own source file or header ... or use the simpler declaration from the man page:
char *strdup(const char *s);
That's not right. strdup returns char * already. Something else is wrong. Probably because you did not include the right header file that declares the true return type for this function.
#include <string.h>
You're missing #include <string.h>. In the absence of function signatures, strdup is assumed by the compiler to return an int, hence the warning.
man strdup
you will get following things
#include<string.h>
char* strdup(const char * s);
so strdup() returns char* there shuld not be any problem
Actually in your case it takes implicit declaration of strdup() so by default return type is int hence you get this warning
Either include<string.h>
or
give forward declaration char* strdup(const char *);
Also don't forget to free(s) in last when all usage are done
all. I'm currently working with an old established code base for a new project which is basically undocumented (i.e. averages 1 one-line comment per file). I just ran into something which I haven't seen before and am not quite sure how to interpret.
Firstly, they define a function type and a function in the header file (.h) in the form:
typedef void (*SOME_FUNCTION)(void *data, EXECUTION_CONTEXT *ec);
void add_function(SOME_FUNCTION aFunction, void *data);
In the main source file (.c), there is a function defined:
void add_function(void (*f)(void *data), void *data)
{
(Some code here)
}
So okay, there's a function pointer... but what the heck happened to the second argument, ec? Why would someone use a code design like this? For reference, when the function add_function is used, it is used in this sort of form:
void passedFunction(void *data, EXECUTION_CONTEXT *ec)
{
(Stuff the function does.)
}
void CallingFunction()
{
data = (some data stuff);
add_function((SOME_FUNCTION)passedFunction, data);
}
So, as you can see, the passed functions use the correct form that fits the original SOME_FUNCTION argument signature, but the definition for the add_function arguments is short by one argument.
Formally, the results are undefined: you are only permitted to call a function via a function pointer if the types match.
As for what actually happens, it depends on the calling convention and what the function does with the arguments. Chances are, the results aren't going to be good.
To add on James' answer:
Since the default calling convention is most likely cdecl, the call site is responsible for cleaning up the stack after passedFunction returns. Since the call site knows that it passed just 1 argument to the callee, the compiler can clean up the stack normally (even though technically this is undefined behavior).
Change the calling convention on passedFunction to stdcall though, and you 're in for some fireworks.
From the example code below, it doesn't appear that the variable(s) that are defined in the function pointer matters during the check. The code below compiles without warning.
#include <stdio.h>
int temp(int (*m)());
int main(int argc, char *argv[]) {
return temp(main);
}
int temp(int (*m)()) {
return 1;
}
However, the code below throws an error.
#include <stdio.h>
int temp(void (*m)());
int main(int argc, char *argv[]) {
return temp(main);
}
int temp(void (*m)()) {
return 1;
}
Due to this; it seems that the compiler (at least in my case GCC) only cares what the return value of the function pointer will be. The interesting thing here is that you CAN send the parameters correctly but if you do NOT specify the parameter (in our example m()), then the variables in m() when called will be junk.