473,414 Members | 1,723 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,414 software developers and data experts.

Function Pointers in C not compiling with g++

Hi
I have header file in C (which cannot be changed).

GraphicsDevice.h
Expand|Select|Wrap|Line Numbers
  1. ---some code---
  2. Rboolean (*open)();
  3. ---code continues
  4.  
Now another code(which also compiles in C) assigns to open like this
dev->open = NULL_Open;

where NULL_Open is defined as
Expand|Select|Wrap|Line Numbers
  1. static Rboolean NULL_Open(NewDevDesc *dev) {
  2.     return TRUE;
  3. }
  4.  
I get the error when compiled with g++
Expand|Select|Wrap|Line Numbers
  1. error: invalid conversion from 'Rboolean (*)(NewDevDesc*)' to 'Rboolean (*)()
  2.  
How can I make g++ ignore this error? Or better, how do i fix it?
Note, I can't change the header file code i.e
Rboolean (*open)();
must stay. Also, i would like NULL_Open to be defined as above (i.e taking a parameter)

Thank you
Saptarshi
Apr 26 '07 #1
6 3244
Hi
I have header file in C (which cannot be changed).

GraphicsDevice.h
Expand|Select|Wrap|Line Numbers
  1. ---some code---
  2. Rboolean (*open)();
  3. ---code continues
  4.  
Now another code(which also compiles in C) assigns to open like this
dev->open = NULL_Open;

where NULL_Open is defined as
Expand|Select|Wrap|Line Numbers
  1. static Rboolean NULL_Open(NewDevDesc *dev) {
  2.     return TRUE;
  3. }
  4.  
I get the error when compiled with g++
Expand|Select|Wrap|Line Numbers
  1. error: invalid conversion from 'Rboolean (*)(NewDevDesc*)' to 'Rboolean (*)()
  2.  
How can I make g++ ignore this error? Or better, how do i fix it?
Note, I can't change the header file code i.e
Rboolean (*open)();
must stay. Also, i would like NULL_Open to be defined as above (i.e taking a parameter)

Thank you
Saptarshi
The error is not be ignored. If you would ignore it the program would crash.

We are dealing with function pointers. The attribute "open" of the object
"dev" is of type "function returning Rboolean* and taking no argument".
You pass a function returning Rboolean* but taking one argument
(NewDevDesc*).

If you would cast the function taking one argument to a function taking
no argument (I better omitt the code here :)) the compiler would not complain.
But later on when you run the program the dev->open attribute comes into
play and the function it points to is called. But, no actual argument is passed
along with it (the stack does not contain anything). Your function thinks an
argument is passed, pops it from the stack and *bang* -> stack underflow.
Apr 27 '07 #2
weaknessforcats
9,208 Expert Mod 8TB
This code:
Expand|Select|Wrap|Line Numbers
  1. ---some code---
  2. Rboolean (*open)();
  3. ---code continues
  4.  
Declares a function pointer variable named "open" as a pointer to a functtion containing no arguments and returning an Rboolean.

You may assign any function address to this pointer PROVIDED the function takes no arguments an Rboolean.

You cannot assign the address of any other function to this and any type casting to get it to compile will just cause a crash when you run the program.

The compiler inists on this becuse your function call using the pointer looks like:
Expand|Select|Wrap|Line Numbers
  1.            Rboolean rval = open();
  2.  
and for this to work the function pointer better contain the address of a function that has no argiments and returns an Rboolean.
Apr 27 '07 #3
Thank you for the replies. I understand the predicament involved in expecting arguments but getting none (because of the declaration and definition contrasts)
But then how does this compile and run in C?
I can say this, because it is part of the R source code (The R Project - a statistical software - the code is in src/library/grDevices/src/devNull.c)
and it works!

I wanted to use QT, so i need to compile with g++

Thank you.
Saptarshi
Apr 27 '07 #4
Hmm, i'm guessing that when the NULL_open is called, it is always called with an argument, though were it to be called with nothing it would crash.
Anyways, assuming it is called with one argument, could you please show me how to recast the function to one that does not take any arguments? ? I ask because I'm learning C++ on this project itself.

Thank you
Saptarshi
Apr 27 '07 #5
weaknessforcats
9,208 Expert Mod 8TB
Thank you for the replies. I understand the predicament involved in expecting arguments but getting none (because of the declaration and definition contrasts)
But then how does this compile and run in C?
I believe this is due to a difference between C and C++. In C:
Expand|Select|Wrap|Line Numbers
  1. Rboolean open();
  2.  
just identifies open as a function. The arguments are based on how the function is called the first time. In C++, however, this means a function that takes no arguments and returns an RBoolean. C++ is not C.
Apr 28 '07 #6
AdrianH
1,251 Expert 1GB
Weaknessforcats is partially correct, though it has nothing to do with how the function is first called. In C, if you do not specify any parameters, it is equivalent to declaring with an ellipsis. In C++, if you do not specify any parameters, it is equivalent to declaring with void.

Expand|Select|Wrap|Line Numbers
  1. /* in C these are equivalent */
  2. void fn();
  3. void fn(...);
  4.  
  5. /* in C++ these are equivalent */
  6. void fn();
  7. void fn(void);
  8.  
If you are to declare a function in C without parameters or using the ellipsis[*], it is legal to define the function with any set of parameters you want. So the following is valid, if not dangerous:
Expand|Select|Wrap|Line Numbers
  1. /* in C the following is valid in header file */
  2. void fn();
  3. /* with the source file defining it like this */
  4. void fn(int foo, float bar)
  5. {
  6.   /* do stuff */
  7. }
  8.  
It is dangerous because you could do a call to fn() with anything, an int and a float as is required, or just a double or even nothing at all. As you can see, the problem with doing this is that if the function is not passed the correct arguments, the compiler will allow it with no warnings. This is REALLY BAD.

There could be some legitimate reason to do this, but I’m tired and can’t think of one at the moment. However, you may be able to allow for this behaviour. To do this, you would need to use the extern "C" { ... } syntax. This would be best done in the header file like this:
Expand|Select|Wrap|Line Numbers
  1. #if defined __cplusplus
  2. extern "C" {
  3. #endif
  4.  
  5. // C prototypes here
  6.  
  7. #if defined __cplusplus
  8. }
  9. #endif
  10.  
If you do not have access to modifying the header file you can try the following, I'm pretty sure it should work:
Expand|Select|Wrap|Line Numbers
  1. extern "C" {
  2. #include "GraphicsDevice.h" // use <> instead of "" if this is a system header
  3. }
  4.  
If this works, fine, but be aware that your header file is a ticking time bomb. If the function is to take a pointer to a NewDevDesc, then it should be put in the C declaration for the function pointer. Otherwise you may inadvertently assign a function to that function pointer which does not take the appropriate parameter. Doing that will cause undefined results such as seg faulting, memory corruption, odd behaviour or if you are extremely lucky, no apparent effect all the time, and if you are unlucky, no apparent effect some of the time.

I would be extremely careful with using this header. I personally hate legacy headers like these and have personally chastised companies for leaving them in for as long as they have.

Hope this helps.


Adrian
[*]NOTE: I think in the newer C specs (or may be all of them), you cannot use an ellipsis without at least one parameter to indicate how many parameters are actually passes like the format string use for printf().
Apr 28 '07 #7

Sign in to post your reply or Sign up for a free account.

Similar topics

1
by: John Miles | last post by:
Hi -- This is a bit of an implementation-specific problem, but I'd like to post it here to see if there's a general answer within the auspices of the language. I'm developing a high(er)-level...
6
by: gustav04 | last post by:
hi all i have a question: what is the difference between a c-function and an c++ class method (both do exactly the same thing). lets say, i have a function called print2std() and a class...
3
by: bnoordhuis | last post by:
Consider this: int foo(int *a, int *b); int (*bar)(void *, void *) = (void *)foo; How legal - or illegal - is the typecast and are there real-world situations where such code will cause...
7
by: Alfonso Morra | last post by:
How can this work ? I have the following declarations in a header: Header ========= typedef void (*VFPTR)(void) ; void FOO_Callback(void*, char*, char*, int, unsigned long, void*,void*);...
7
by: Bryan Parkoff | last post by:
C/C++ Compiler encourages to limit 1,000 functions under function pointer, but I am allowed to overlimit 4,096 functions. I am just for fun to test how it works. The problem is that source code...
8
by: Klaas Vantournhout | last post by:
Hi all, I'm in need of a matrix of function pointers, and to be honest. No 'nice' solution has been found yet on that big big internet. It is possible to declare a matrix of function pointers...
5
by: mancomb | last post by:
Hi, I'm curious to the syntax of calling member functions through pointers of classes returned through the -operator. For example (excuse the crude incomplete code); Here are the classes: ...
57
by: Robert Seacord | last post by:
i am trying to print the address of a function without getting a compiler warning (i am compiling with gcc with alot of flags). if i try this: printf("%p", f); i get: warning: format %p...
4
by: zaeminkr | last post by:
I got a good answer here I have still confusing part. I have two very simple classes class DRect { private : double x0, y0, x1, y1; public : DRect(double a, double b, double c, double d) :...
4
by: Josefo | last post by:
Hello, is someone so kind to tell me why I am getting the following errors ? vector_static_function.c:20: error: expected constructor, destructor, or type conversion before '.' token...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.