Could Someone Try Compiling This On A Different Compiler

Thread Solved

Join Date: Jan 2008
Posts: 344
Reputation: gerard4143 is on a distinguished road 
Solved Threads: 44
gerard4143's Avatar
gerard4143 gerard4143 is offline Offline
Posting Whiz

Could Someone Try Compiling This On A Different Compiler

 
0
  #1
16 Days Ago
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

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. unsigned long testval = 1234;
  5.  
  6. void* foundit(void)
  7. {
  8. fputs("found it!\n", stdout);
  9. return (void*)0;
  10. }
  11.  
  12. void* tryit(void)
  13. {
  14. unsigned long val;
  15.  
  16. fputs("enter a value/guess->", stdout);
  17. fscanf(stdin, "%u", &val);
  18.  
  19. if (val == testval)
  20. {
  21. return (void*)&foundit;
  22. }
  23. else
  24. {
  25. return (void*)&tryit;
  26. }
  27. }
  28.  
  29. int main(int argc, char**argv)
  30. {
  31. void *addr = (void*)&tryit;
  32.  
  33. //fprintf(stdout, "ans->%u\n", 1); //remove comments and program runs
  34. //but fails to exit with correct value
  35. while ((addr = ((void*(*)(void))addr)()))
  36. {}
  37. exit(EXIT_SUCCESS);
  38. }
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,339
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1460
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning
 
-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:
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.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 344
Reputation: gerard4143 is on a distinguished road 
Solved Threads: 44
gerard4143's Avatar
gerard4143 gerard4143 is offline Offline
Posting Whiz
 
0
  #3
16 Days Ago
Originally Posted by Ancient Dragon View Post
>>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() )
No the complier had no problems casting a void pointer to a function..should it?
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

  1. //fprintf(stdout, "ans->%u\n", 1);

The program fails to exit correctly...Note the program works as intended while the comments are there...
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,339
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1460
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning
 
-1
  #4
16 Days Ago
Worked fine for me using vc++ 2008 express
ans->1
enter a value/guess->1234
found it!
Press any key to continue . . .
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.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 344
Reputation: gerard4143 is on a distinguished road 
Solved Threads: 44
gerard4143's Avatar
gerard4143 gerard4143 is offline Offline
Posting Whiz
 
0
  #5
16 Days Ago
Originally Posted by Ancient Dragon View Post
Worked fine for me using vc++ 2008 express
Humph...That means I'm going have to walk through some assembler and find out why removing the comments from this line

  1. 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
Reply With Quote Quick reply to this message  
Join Date: Aug 2005
Posts: 15,339
Reputation: Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute Ancient Dragon has a reputation beyond repute 
Solved Threads: 1460
Team Colleague
Featured Poster
Ancient Dragon's Avatar
Ancient Dragon Ancient Dragon is offline Offline
Still Learning
 
-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.
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.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 344
Reputation: gerard4143 is on a distinguished road 
Solved Threads: 44
gerard4143's Avatar
gerard4143 gerard4143 is offline Offline
Posting Whiz
 
0
  #7
16 Days Ago
Well I tried compiling the code on GCC 4.3.2 and it worked. I think GCC 4.4.1 may be in need of an update...Thanks again Ancient Dragon

So to recap:

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 and vc++ 2008 express
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,580
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 709
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess
 
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):
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. unsigned long testval = 1234;
  5.  
  6. /*
  7. Define a generic function pointer
  8. type for temporary conversion
  9. */
  10. typedef void (*func_t)(void);
  11.  
  12. /*
  13. Define a null value with the
  14. generic function pointer type
  15. */
  16. void null_func(void) { }
  17.  
  18. func_t foundit(void)
  19. {
  20. fputs("found it!\n", stdout);
  21. return null_function; /* No cast needed */
  22. }
  23.  
  24. func_t tryit(void)
  25. {
  26. unsigned long val;
  27.  
  28. fputs("enter a value/guess->", stdout);
  29.  
  30. /* Note the format specifier. %u was incorrect */
  31. fscanf(stdin, "%lu", &val);
  32.  
  33. if (val == testval)
  34. {
  35. return (func_t)foundit; /* Safe cast */
  36. }
  37. else
  38. {
  39. return (func_t)tryit; /* Safe cast */
  40. }
  41. }
  42.  
  43. int main()
  44. {
  45. func_t addr = (func_t)tryit; /* Safe cast */
  46.  
  47. fprintf(stdout, "ans->%u\n", 1U);
  48.  
  49. while (addr != null_func) {
  50. /* Cast back to the correct type before calling */
  51. addr = ((func_t(*)(void))addr)();
  52. }
  53.  
  54. /* A call to exit really isn't necessary from main */
  55. return 0;
  56. }
>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.
I'm here to prove you wrong.
Reply With Quote Quick reply to this message  
Join Date: Jan 2008
Posts: 344
Reputation: gerard4143 is on a distinguished road 
Solved Threads: 44
gerard4143's Avatar
gerard4143 gerard4143 is offline Offline
Posting Whiz
 
0
  #9
15 Days Ago
Originally Posted by Narue View Post
>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.
Could you give an example....
Last edited by gerard4143; 15 Days Ago at 11:05 am.
Reply With Quote Quick reply to this message  
Join Date: Sep 2004
Posts: 7,580
Reputation: Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute Narue has a reputation beyond repute 
Solved Threads: 709
Team Colleague
Narue's Avatar
Narue Narue is offline Offline
Code Goddess
 
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:
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.
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:
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.
Reply With Quote Quick reply to this message  
Reply

This thread has been marked solved.
Perhaps start a new thread instead?
Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC