| | |
Could Someone Try Compiling This On A Different Compiler
Please support our C advertiser: Programming Forums - DaniWeb Sister Site
Thread Solved |
I wrote this very small program that works fine until I remove the comments for the fprintf function.
Basically the program will prompt the user for a numeric value, when the user guesses right(1234) the program exits. When I remove the comments the program never exits...Does anyone have any idea why? I'm completely lost as to why it would behave like this...maybe its my compiler - gcc 4.4.1
Basically the program will prompt the user for a numeric value, when the user guesses right(1234) the program exits. When I remove the comments the program never exits...Does anyone have any idea why? I'm completely lost as to why it would behave like this...maybe its my compiler - gcc 4.4.1
C Syntax (Toggle Plain Text)
#include <stdio.h> #include <stdlib.h> unsigned long testval = 1234; void* foundit(void) { fputs("found it!\n", stdout); return (void*)0; } void* tryit(void) { unsigned long val; fputs("enter a value/guess->", stdout); fscanf(stdin, "%u", &val); if (val == testval) { return (void*)&foundit; } else { return (void*)&tryit; } } int main(int argc, char**argv) { void *addr = (void*)&tryit; //fprintf(stdout, "ans->%u\n", 1); //remove comments and program runs //but fails to exit with correct value while ((addr = ((void*(*)(void))addr)())) {} exit(EXIT_SUCCESS); }
-7
#2 Nov 7th, 2009
>>while ((addr = ((void*(*)(void))addr)())
Didn't your compiler produce an error or warning on that line?? tryit() does not return a value, yet in the above addr is being assigned the return value of tryint(). You can't have it both ways. try this:
Didn't your compiler produce an error or warning on that line?? tryit() does not return a value, yet in the above addr is being assigned the return value of tryint(). You can't have it both ways. try this:
while( addr() ) Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
0
#3 Nov 7th, 2009
•
•
•
•
>>while ((addr = ((void*(*)(void))addr)())
Didn't your compiler produce an error or warning on that line?? tryit() does not return a value, yet in the above addr is being assigned the return value of tryint(). You can't have it both ways. try this:
while( addr() )
And for tryit() the if statement assures that the function returns a value..
But that isn't the problem...The problem is when I remove the comments from this line
C Syntax (Toggle Plain Text)
//fprintf(stdout, "ans->%u\n", 1);
The program fails to exit correctly...Note the program works as intended while the comments are there...
0
#5 Nov 7th, 2009
Humph...That means I'm going have to walk through some assembler and find out why removing the comments from this line
causes the program to behave differently...well besides printing 1 to the display..
Thanks for trying the program Ancient Dragon
C Syntax (Toggle Plain Text)
fprintf(stdout, "ans->%u\n", 1);
causes the program to behave differently...well besides printing 1 to the display..
Thanks for trying the program Ancient Dragon
-7
#6 Nov 7th, 2009
>>well besides printing 1 to the display..
The reason for that should be obvious.
Also compiled with Code::Blocks using MinGW (gcc 3.4.5) and it worked ok.
The reason for that should be obvious.
Also compiled with Code::Blocks using MinGW (gcc 3.4.5) and it worked ok.
Last edited by Ancient Dragon; Nov 7th, 2009 at 9:38 pm.
Don't PM me with questions -- you might get a nasty PM in response. If you have a question then post it in one of the forums.
2
#8 Nov 8th, 2009
>No the complier had no problems casting a void pointer to a function..should it?
It might. Technically void* and functions pointers are incompatible and converting between them is undefined behavior. I've seen compilers give both warnings and errors for such a conversion. The good news is that you can avoid this problem entirely by taking advantage of the fact that any function pointer type can be converted to any other function pointer type and back with well defined behavior (provided you call the function pointer with the correct type):
>But that isn't the problem...
>The problem is when I remove the comments from this line
It might actually be. In my experience, when commenting out random unrelated lines suddenly causes a broken program to work, it's often a result of undefined behavior.
>the code will not work correctly on GCC 4.4.1
>but it will work correctly on GCC 4.3.2, GCC 3.4.5
File a bug report and see what comes of it then.
It might. Technically void* and functions pointers are incompatible and converting between them is undefined behavior. I've seen compilers give both warnings and errors for such a conversion. The good news is that you can avoid this problem entirely by taking advantage of the fact that any function pointer type can be converted to any other function pointer type and back with well defined behavior (provided you call the function pointer with the correct type):
C Syntax (Toggle Plain Text)
#include <stdio.h> #include <stdlib.h> unsigned long testval = 1234; /* Define a generic function pointer type for temporary conversion */ typedef void (*func_t)(void); /* Define a null value with the generic function pointer type */ void null_func(void) { } func_t foundit(void) { fputs("found it!\n", stdout); return null_function; /* No cast needed */ } func_t tryit(void) { unsigned long val; fputs("enter a value/guess->", stdout); /* Note the format specifier. %u was incorrect */ fscanf(stdin, "%lu", &val); if (val == testval) { return (func_t)foundit; /* Safe cast */ } else { return (func_t)tryit; /* Safe cast */ } } int main() { func_t addr = (func_t)tryit; /* Safe cast */ fprintf(stdout, "ans->%u\n", 1U); while (addr != null_func) { /* Cast back to the correct type before calling */ addr = ((func_t(*)(void))addr)(); } /* A call to exit really isn't necessary from main */ return 0; }
>The problem is when I remove the comments from this line
It might actually be. In my experience, when commenting out random unrelated lines suddenly causes a broken program to work, it's often a result of undefined behavior.
>the code will not work correctly on GCC 4.4.1
>but it will work correctly on GCC 4.3.2, GCC 3.4.5
File a bug report and see what comes of it then.
New members chased away this month: 3
2
#10 Nov 8th, 2009
>Could you give an example....
Your code is an example, my fix for your code is a counter-example. What more do you want? How about a quote from the standard:
The key terms here are incomplete and object type. An object type is distinct from a function type, and incomplete types are defined as object types that lack size information.
I said "technically" in my original post because even the standard lists this as a common extension:
Your code is an example, my fix for your code is a counter-example. What more do you want? How about a quote from the standard:
•
•
•
•
Originally Posted by C99 Section 6.3.2.3
1 A pointer to void may be converted to or from a pointer to any incomplete or object
type. A pointer to any incomplete or object type may be converted to a pointer to void
and back again; the result shall compare equal to the original pointer.
I said "technically" in my original post because even the standard lists this as a common extension:
•
•
•
•
Originally Posted by C99 Section J.5.7
1 A pointer to an object or to void may be cast to a pointer to a function, allowing data to
be invoked as a function (6.5.4).
2 A pointer to a function may be cast to a pointer to an object or to void, allowing a
function to be inspected or modified (for example, by a debugger) (6.5.4).
New members chased away this month: 3
![]() |
Similar Threads
- Header files, C++ vs C compiler question (C++)
- Binary Recursion Function Errors - Help!! (C++)
- Time function (C)
- EOL is not working and uncheck or unsafe operation (Java)
- urgent help required plz help (C)
- Compatibility problems (Java)
- how will i repeat my whole game program? (Java)
Other Threads in the C Forum
- Previous Thread: Small C program error
- Next Thread: Need Help sorting structures
| Thread Tools | Search this Thread |
Tag cloud for C
adobe ansi api array arrays asterisks binarysearch calculate centimeter char convert copyimagefile copypdffile cprogramme creafecopyofanytypeoffileinc createcopyoffile csyntax directory dynamic fflush file fork forloop frequency getlasterror givemetehcodez graphics gtkgcurlcompiling hacking hardware highest homework i/o inches incrementoperators infiniteloop interest kernel km lazy linked linkedlist linux linuxsegmentationfault list lists locate logical_drives match matrix microsoft motherboard multi mysql number open opendocumentformat opensource owf pattern pdf performance pointer pointers posix problem probleminc program programming pyramidusingturboccodes radix read recursion recv repetition research scanf scheduling scripting segmentationfault send sequential shape socketprograming spoonfeeding stack standard string strings structures student systemcall testautomation turboc unix user variable voidmain() wab windows.h






