Availability of a function? - c

I just noticed that a function, which is passed as an argument in C, is no more available in the main function for direct calling. the compilation of the code below produces the error
"../main.c:22:8: error: called object ‘hello’ is not a function or function pointer"
Code:
#include<stdio.h>
void hello(void)
{
printf("hello there\n");
}
void main(hello)
{
int y = 100;
printf("%i",y);
if (y==100)
hello();
}
is it the case or I did something wrong?
EDIT: I changed the main call to - void main(void hello (void)) Now there is no error in compilation but still the call to hello function after IF statement doesn't execute printf statement.
EDIT NO 2 : After reading many answer, I learnt that we can pass a pointer to a function as an argument to another function. passing whole function as argument is meaningless. Actually, this whole confusion arose out of the following opengl C code, which apparently ran successful in Eclipse IDE:
#include <GL/glut.h>
#include<GL/gl.h>// Header File For The GLUT Library
void init(void)
{
glClearColor (0.0,0.0,0.4,0.0);
glShadeModel(GL_FLAT);
}
void reshape (int w, int h)
{
glViewport(0,0, (GLsizei) w, (GLsizei)h); // indicates the shape of the available screen area into which the scene is mapped
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(-10,10,-10,10,-10,10);
}
void display (void)
{
int i,j;
while(1){
for (i=-10; i <=10; i++){
glClearColor (0.0,0.0,0.0,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(0.0, 0.0, 1.0);
glBegin(GL_TRIANGLES);
glVertex3f(i,2,5);
glVertex3f(6,-i,-5);
glVertex3f(1,9,-1);
glEnd();
glFlush();}
}
}
int main (int argc, char *argv[])
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB);
glutInitWindowPosition(100,100);
glutInitWindowSize(500,500);
glutCreateWindow (argv[0]);
init ();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
glutMainLoop ();
return 0;
}
Here if you notice the call glutDisplayFunc(display) APPARENTLY passes the display function as an argument.How this is happening?

You've managed to blur things horribly.
void main(hello) declares main (incorrectly) as returning nothing and taking a single argument of type int (implicit int). You can't call an int; hence your local variable hides the external function of the same name. The C89 and pre-standard C allowed the 'implicit int' notation; it is officially not allowed in C99 or C11, though many compilers will continue to allow it unless you ask them for warnings.
You should declare main() as either:
int main(void)
int main(int argc, char **argv)
Windows does allow void main(), sadly. C++ does not.
If you use GCC, compile with options like -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Wold-style-declaration (preferably with -Werror). Not all versions of GCC support all those options; use those that your version does support.
Incidentally, by declaring hello as an argument to main(), you are hiding or shadowing the external definition of the hello() function. This is standard C behaviour; a name defined at local scope hides different objects with the same name defined at outer scope levels. You can use the -Wshadow option to GCC to spot when you run into this as a problem.
Post-Edit
As I already asked, why on earth do you think the startup environment is going to pass a pointer-to-function to your main()?
The function definition:
void main(void hello(void))
still does not match one of the acceptable patterns.
Further, the startup code won't pass a pointer to function to your main(); it will basically call your code as if you'd written int main(int argc, char **argv) (or possibly int main(int argc, char **argv, char **envp)). You are guaranteed not to get a pointer-to-function passed to your main().
So, whatever else happens, you will not be successful. Typically, the value of argc (and perhaps part of argv) will be treated as a pointer to function (even though it isn't). All hell will break loose.
Simply define:
int main(void)
and call hello() directly in the body of main(). That's about all that makes sense.
For the record, this is what GCC says about the code in the question (as amended):
$ gcc -O3 -g -I/Users/jleffler/inc -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition -Werror -Wshadow -c hello.c
hello.c:3:6: error: no previous prototype for ‘hello’ [-Werror=missing-prototypes]
void hello(void)
^
hello.c:8:6: error: return type of ‘main’ is not ‘int’ [-Werror=main]
void main(void hello (void))
^
hello.c:8:6: error: first argument of ‘main’ should be ‘int’ [-Werror=main]
hello.c:8:6: error: ‘main’ takes only zero or two arguments [-Werror=main]
hello.c: In function ‘main’:
hello.c:8:16: error: declaration of ‘hello’ shadows a global declaration [-Werror=shadow]
void main(void hello (void))
^
hello.c:3:6: error: shadowed declaration is here [-Werror=shadow]
void hello(void)
^
cc1: all warnings being treated as errors
$
Passing pointers to functions — the OpenGL code
You can pass a pointer-to-function as an argument to any function that expects such an argument. However, main() is one of the functions you can't tinker with (the functions in the Standard C library should be treated as 'cannot be changed' either; ditto the operating system interfaces for the platform(s) you use).
In your OpenGL example code, it is perfectly legitimate to pass a function pointer like display or reshape to the glutDisplayFunc() and glutReshapeFunc() functions because they are designed to accept pointers to functions. Had you written your initial offering as:
#include <stdio.h>
static void hello(void)
{
printf("hello there\n");
}
static void invoke(void (*function)(void))
{
printf("-->> %s:\n", __func__);
function(); // Or (*function)();
printf("<<-- %s\n", __func__);
}
int main(void)
{
int y = 100;
printf("%i\n", y);
if (y == 100)
invoke(hello);
return 0;
}
there would have been no outcry from anyone — compiler or human. This is clean (C99 or C11) code that helps in understanding pointers to functions. If you write void invoke(void function(void)) without the explicit pointer, the compiler automatically converts the type to 'pointer to function taking no arguments and returning no value — aka void (*function)(void). So, you can write that if you prefer, though I prefer the explicit pointer notation, not least because inside a function, or as a global variable, you must use the explicit pointer notation, so using that with function arguments is consistent. Inside a function, writing:
void function(void);
declares a function, not a pointer to function variable; that must be written:
void (*function)(void) = hello; // Note no parentheses on hello!
Similarly at with variables at file scope. So, using the void (*function)(void) notation in function argument lists (in prototypes and definitions) is consistent with the rest of the language and is therefore the better notation to use.

The parameter hello shadows the global hello, so all appearances of hello within main refer to the parameter, not the function. And since the parameter is of type int (because you didn't specify a type and int is the default) and ints aren't functions (or function pointers), that's a type error.

main(hello)
is wrong
use
main()

Related

I want to implement a stack but printf throws a segmentation fault

I want to implement a stack using structures in C. Unfortunately, printf throws a segmentation fault. Perhaps there is a problem with dynamic allocation. Does anyone know how to solve it?
I have been facing this issue for the last two days. Your help will be very helpful for my study.
Here is my code
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#define SIZE 256
typedef int (*pf)();
typedef struct _stack{
int arr[SIZE];
int top;
pf push, pop, peek, isEmpty, size, clear, print;
} stack;
void *nstack(){
stack *pstack = (stack *)malloc(sizeof(stack));
void push(int data) {
if(pstack->top < SIZE-1) pstack->arr[++pstack->top]=data;
}
int pop() {
return (pstack->top >= 0)?pstack->arr[pstack->top--]:0;
}
int peek(){
return (pstack->top >= 0)?pstack->arr[pstack->top]:0;
}
bool isEmpty(){
return (pstack->top >= 0)?false:true;
}
int size(){
return pstack->top+1;
}
void clear(){
pstack->top = -1;
}
void print(){
if(!isEmpty()){
for(int i = 0; i <= pstack->top; i++) printf("%d", pstack->arr[i]);
printf("\n");
}
}
pstack->push=push;
pstack->pop=pop;
pstack->peek=peek;
pstack->isEmpty=isEmpty;
pstack->size=size;
pstack->clear=clear;
pstack->print=print;
pstack->top=-1;
return pstack;
}
void dstack(stack *pstack){
free(pstack);
}
void main() {
stack *A = nstack();
A->push(1);
A->push(4);
A->push(6);
printf("%d",A->pop());
printf("%d",A->pop());
dstack(A);
}
While the code compiles (with warning), it try to leverage GCC extensions for functions within functions. However, the internal functions must be called within a valid context - they try to access the local pstackof the nstack function - but it does not exists.
While this style work in many OO langauges (Java, and possibly C++), that support 'closures' or lambda, it does not work for C. Consider changing the interface for each of the function to take stack *, and change the calling sequence to pass it.
void push(stack *pstack, int data) {
if(pstack->top < SIZE-1) pstack->arr[++pstack->top]=data;
}
main() {
...
A->push(A, 1) ;
...
printf("%d", A->pop(A) ;
}
Really, you should edit your question and provide the exact errors but I've decided to do some of the legwork for you since you're probably pretty new to this.
So first thing I did was compile your code here with -Wall and look what I get:
SO_stack.c: In function ‘nstack’:
SO_stack.c:49:17: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
pstack->push=push;
^
SO_stack.c:52:20: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
pstack->isEmpty=isEmpty;
^
SO_stack.c:54:18: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
pstack->clear=clear;
^
SO_stack.c:55:18: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
pstack->print=print;
^
SO_stack.c: At top level:
SO_stack.c:66:6: warning: return type of ‘main’ is not ‘int’ [-Wmain]
void main() {
Let's look at the first error on line 49: pstack->push=push;
You've defined push function prototype as: void push(int data) but pstack->push is of type pf which is defined as int (*pf)(); See the problem here? You're trying to pass an argument to a function pointer that is not properly defined to handle the argument AND the return type is different. This is totally wrong. Your push(int data) implementation declares a return type of void and a parameter of int yet your pointer to this function declares a return type of int and a parameter of void. This is the case with push, isEmpty, clear, and print. You're going to have to decide if all of these functions need to have the same prototype or if you need to create several different function pointer types to handle them, etc...
So that's the first problem.
Second problem is that as the warning says, you have a void main() prototype for your main function. You should return int from main and specify a return code to the caller of main (likely the OS)... Commonly, successful execution returns 0 and failure returns -1 but this is specific to the platform so you can instead return EXIT_SUCCESS on success and return EXIT_FAILURE upon failure from main. For this macros to be defined, you need to have #include <stdlib.h> present, which you do.
Next issue is that as a commenter wrote, you should learn to use a debugger such as GDB, LLDB, or Windows Debugger so that you can figure out exactly where the program crashes.
I've not re-written your program because it has so many issues that I don't think it would be constructive to do so in this iteration, however, provide an exact error next time, and use the debugger to see if the crash happens inside of the actual printf() code as you implied, or it happens because you supplied corrupt memory to the printf function. My guess is that it is the latter... Meaning, it is in fact probably your code which is flawed and supplying an invalid char * to printf which is either out of bounds, nonexistent, etc... This is precisely what you will use a debugger to find out, by placing a breakpoint before the trouble code and watching the memory to see what's going on.
You need to either remove int data.
Work on this some more, and you will probably find the rest of the issues yourself, if there are any. You should compile with flag -Wall and consider compiling with flag -Werror to clear this kind of stuff up yourself in the future.

Passing parameters to function in different file (gcc)

I wrote an add function for int in Add.c. Then, I passed real numbers to this add function in Main.c. The codes are shown as follows.
If I have declaration of add function before calling it, the answer is correct as 30. However, if the declaration does not exist, the answer is incorrect. Why?
Add.c
int add(int x, int y) { return x + y;}
Main.c
#include<stdio.h>
int add(int, int); // If this does not exist, the answer is not 30.
int main(void) {
printf("%d\n", add(10.5, 20.5));
}
Without the declaration, which is more specifically a prototype (a declaration with specified parameter types), you're relying on an implicit prototype-less declaration of the function (which is now an obsolescent feature of C).
The implicit prototype for function f is int f()—a function returning int and taking an unspecified number of parameters.
The way functions without prototypes are called is the arguments are promoted (lesser than int integer types to int and floats to doubles) and passed to the function in an implementation-defined way. If the arguments don't match the definition, the behavior is undefined (your case).
You could fix this (while still relying on the implicit declaration) by providing explicit casts:
#include<stdio.h>
//nothing (probably will get a compiler warning) or
int add(); /*=params unspecified*/
int main(void) {
printf("%d\n", add((int)10.5, (int)20.5));
}
thereby removing the UB (undefined behavior), or you can include the prototype as you have, which will make the compiler convert passed-in floats to match the expected types (int). In other words, with the prototype, the compiler will insert these casts for you, seeing that a conversion from float to int in (argument) assignment.
The preferred way to solve this is with a prototype included via a header which is also included in the implementation file (Add.c) so as to allow to compiler to verify the call is consistent with the definition.
To make this work, first of all, you have to include the "add.c" file into the "main.c". Coz main.c doesn't know about "add" function in add.c. (Also you should not make '.c' file to add a function or something. Instead use '.h')
Now the solution should look like this...
add.h
int add(int x, int y){
return x + y;
}
main.c
#include<stdio.h>
#include "add.h"
int main(void){
printf("%d\n", add(10, 20));
return 0;
}
Make sure to keep both the files in same directory.
Before using add in Main.c, it needs to know the declaration for this function. Without using function prototype in this case the behavior of the program would be undefined. You can either add a prototype before main as you did or you can create a separate Add.h file and put the prototype there.
In second case you need to add Add.h to both .c files.
Add.h
#ifndef ADD_H
#define ADD_H
int add(int x, int y;
#endif
Add.c
#include "Add.h"
int add(int x, int y) { return x + y;}
Main.c
#include<stdio.h>
#inclide "Add.h"
int main(void) {
printf("%d\n", add(10, 20));
}

Global variable initialized to 1 instead of 0 in my C program

If I have, suppose, initialized a global variable F, and print its value in main function, 0 will be printed (as it should be).
But when i pass the argument int F in the main function while declaring the global variable F in exact same way as before, printing the value of F using gcc prints 1.
Can anyone explain why is that?
This is my code below.
#include<stdio.h>
int F;
int main(int F){
printf("F is %d\n", F);
return 0;
}
When your main function contains an argument with the same name as a global variable then the stub is refered to the local variable .. not the global variable
#include <stdio.h>
static int F;
int main(){
printf("F is %d", F);
return 0;
}
But when i pass the argument int F in the main function  ? that F is nothing but argument count i.e argc.
In particular case you mentioned global F and F you declared in main() argument are different.
int main(int F){ printf("F is %d\n", F); return 0; }
Here printf() prints 1 because when you run your executable like ./a.out no of command line input is 1, it's similar to argc.
Your compiler could have warn you about argument provided to main(), compile with -Wall flag and read the warning. Also check the main() prototype. From the C standard
ISO/IEC 9899:1999
§5.1.2.2.1 Program startup
¶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 intand with no parameters:
int main(void) { /* ... */ }
or with two parameters (referred to here as argc and argv, though any
names may be used, as they are local to the function in which they are
declared):
int main(int argc, char argv[]) { / ... */ }
or equivalent;9) or in some other implementation-defined manner.
In your posted code, main has an argument named F. Inside main, any references to F refer that variable, not the global one.
You make life unnecessarily harder by using improper names of variables. Most of the time, the arguments to main are named argc and argv -- argument count and argument values.
int main(int argc, char** argv) { ... }
It's good to use variable names that have meaning. Using int F; as a global variable is not meaningful either. Name it such that it is meaningful. Then, you will run into problems like you did a lot less.
You should make main() conform to the requirements of the standard, and you should print the global F as well as the argument F:
#include <stdio.h>
int F;
int main(int F, char **G)
{
printf("F is %d\n", F);
{
extern int F;
printf("%s: F is %d\n", G[0], F);
}
return 0;
}
When compiled (from source file quirky43.c to program quirky43), and run, I get:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror quirky43.c -o quirky43
$ ./quirky43
F is 1
quirky43: F is 0
$ ./quirky43 this is why you get command line arguments
F is 9
quirky43: F is 0
$
The first printf() is printing the first argument to main() (conventionally called argc, but there's nothing wrong with calling it F except that it is unexpected). The second one prints the global variable F (and also the program name, conventionally argv[0] but again there's nothing wrong with using G except that it is unexpected). The extern int F; inside a set of braces means that F in that statement block refers to a variable F defined outside the enclosing scope, which means the file scope variable F — which, it may be noted, is correctly initialized to 0. The 1 comes because you invoked the program without arguments, and the argument count includes the program name. It's also why the value printed was 9 when 8 arguments were added to the command line.
Note that another good compilation option to use is -Wshadow:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wshadow quirky43.c -o quirky43
quirky43.c: In function ‘main’:
quirky43.c:6:14: error: declaration of ‘F’ shadows a global declaration [-Werror=shadow]
int main(int F, char **G)
~~~~^
quirky43.c:4:5: note: shadowed declaration is here
int F;
^
cc1: all warnings being treated as errors
$
(Compilation with GCC 8.1.0 on a Mac running macOS High Sierra 10.13.5.)

conflicting type for funct in C

I am trying to run the code below and i am getting the error messages below.
Program:
int main()
{
int (*res)[3],i;
res=func();
}
int (*func())[3]
{
static int arr[3][3]={1,2,3,4,5,6,7,8,9};
return arr;
}
Error:
PointerTo1D.c: In function ‘main’:
PointerTo1D.c:6:5: warning: assignment makes pointer from integer without a cast [enabled by default]
res=func();
^
PointerTo1D.c: At top level:
PointerTo1D.c:11:7: error: conflicting types for ‘func’
int (*func())[3]
^
PointerTo1D.c:6:6: note: previous implicit declaration of ‘func’ was here
res=func();
Could someone please help me out here???
res is a pointer to an array with 3 elements of int
int (*func())[3]: func is a function which returns a pointer to array with 3 elements of int
Because there is no prototype for function func() you got:
warning: implicit declaration of function 'func'
res=func();
which means that compiler use default prototype int func().
There is next warning:
warning: assignment makes pointer from integer without a cast [enabled by default]
res=func();
because default prototype is used, compiler assumes that function func() returns int which is than assigned as a pointer to res which is the pointer
When code for function func() is reached you get error:
error: conflicting types for 'func'
int (*func())[3]
Solution is to provide proper prototype before main.
int (*func())[3];
int main()
{
...
}
Update: There is also warning:
warning: missing braces around initializer [-Wmissing-braces]
static int arr[3][3]={1,2,3,4,5,6,7,8,9};
It is better to use:
static int arr[3][3]={{1,2,3}, {4,5,6}, {7,8,9}};
You have to change your code to
int** func() //change here
{
static int arr[3][3]={1,2,3,4,5,6,7,8,9};
return arr;
}
and
int** func(); //forward declaration
int main()
{
int ** res = NULL,i = 0; //change here
res=func();
return 0;
}
Any function you call from your main() should either be defined before main() or atleast have a forward declaration before main() so that the comipler has a way to know the function signature before the function is used (called).
Note: Usually, it's not a good practice to use static for this purpose. Dynamic memory allocation (malloc()/calloc()) is designed exactly for this purpose.
First if you want to return a pointer do like this :
(int **)func() {
...
return arr;
}
Then define res like this :
int ** res;
res = func();
If a function is called without a declaration being visible, it is assumed to be old-style declared, with external linkage, and returning an int in C89:
extern int func();
The empty parentheses (an old-style declaration) mean: No argument checking required, function takes fixed number of default-promoted arguments.
In C99, implicit declarations have been removed, Gcc warns about them by default, but sticks to the old behaviour, probably for backward compatibility. They can be turned into errors for example with gcc -std=c99 -pedantic-errors, or gcc -std=gnu89 -Werror=implicit-function-declaration if you want to stick to GNU89 (what I suspect was specified from the warnings given).
To fix the problem, the function needs at least to be declared before use:
int (*func())[3];
int main() {
func();
}
This still uses old-style declarations, marked obsolescent in all C standards, I'd suggest using prototypes to ensure argument checking:
int (*func(void))[3];
int main(void) { /* ... */ }

ISO C Void * and Function Pointers

While following some tutorials and reading about function pointers I learned that evidently assigning a void pointer to a function pointer in ISO C is undefined, is there any way to resolve the warning I receive during compile time (e.g. a better way of coding it) or should I just ignore it?
Warning:
ISO C forbids assignment between function pointer and 'void *' [-pedantic]
Example Code:
void *(*funcPtr)();
funcPtr = GetPointer();
GetPointer is a function that returns a void pointer E.G.
void *GetPointer();
In tlpi-book I found this trick very interesting:
#include <dlfcn.h>
int
main(int argc, char *argv[])
{
...
void (*funcp)(void); /* Pointer to function with no arguments */
...
*(void **) (&funcp) = dlsym(libHandle, argv[2]);
}
No. The compiler is right, and you too: in C89 and C99, you can't convert between data pointers (which void * is) and function pointers, so the only way for resolving the warning is returning a function pointer from the function.
(Note, however, that in practice this works despite the warning, and even there's this inconsistency in the standard library - the dlsym() function is used for obtaining function pointers, but it returns void * - so essentially you can ignore the warning. It will work, although strictly speaking the behavior is undefined here.)
I encountered this problem using glib. Glib data structures, such as GSList usually have a field called void *data. I wanted to store functions in a list and got a bunch of errors similar to this:
warning: ISO C forbids passing argument 2 of ‘g_slist_append’ between function pointer and ‘void *’ [-pedantic]
This example generates a bunch of warnings using gcc -Wall -ansi -pedantic
typedef int (* func) (int);
int mult2(int x)
{
return x + x;
}
int main(int argc, char *argv[])
{
GSList *functions = NULL;
func f;
functions = g_slist_append(functions, mult2);
f = (func *) functions->data;
printf("%d\n", f(10));
return 0;
}
So I wrapped the function in a struct and all the warnings go away:
struct funcstruct {
int (* func) (int);
};
int mult2(int x)
{
return x + x;
}
int main(int argc, char *argv[])
{
GSList *functions = NULL;
struct funcstruct p;
p.func = mult2;
functions = g_slist_append(functions, &p);
p = * (struct funcstruct *) functions->data;
printf("%d\n", p.func(10));
return 0;
}
It's arguable that this is quite a bit of extra code to make a few warnings disappear, but I don't like my code to generate warnings. Also, the above are toy examples. In the real code I'm writing, it turns out to be quite useful to wrap the list of functions in a struct.
I'd be interested to hear if this is problematic or if there's a better way of doing it.

Resources