| | |
Could Someone Try Compiling This On A Different Compiler
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); }
-1
#2 16 Days Ago
>>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 16 Days Ago
•
•
•
•
>>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 16 Days Ago
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
-1
#6 16 Days Ago
>>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; 16 Days Ago 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.
0
#8 15 Days Ago
>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.
I'm here to prove you wrong.
0
#10 15 Days Ago
>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).
I'm here to prove you wrong.
![]() |
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 |
* adobe ansi api array arrays binarysearch calculate centimeter char character cm convert copyanyfile copypdffile cprogramme createcopyoffile createprocess() csyntax directory dynamic feet fflush file floatingpointvalidation fork forloop frequency getlasterror getlogicaldrivestrin givemetehcodez global graphics gtkgcurlcompiling gtkwinlinux hacking highest homework i/o inches incrementoperators intmain() iso km linked linkedlist linux linuxsegmentationfault list locate logical_drives loopinsideloop. lowest match matrix microsoft mqqueue mysql oddnumber odf open opendocumentformat openwebfoundation pattern pdf performance pointer posix power program programming pyramidusingturboccodes read recursion recv recvblocked repetition reversing scanf scheduling segmentationfault send shape single socketprograming socketprogramming stack standard strchr string suggestions test unix urboc user variable voidmain() whythiscodecausesegmentationfault win32api windows.h






