Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Aug 27, 2008, 06:39 PM   #1
ChrisA
macrumors G4
 
Join Date: Jan 2006
Location: Redondo Beach, California
C is platform specific?

I just fixed an obvious bug in a C program
Code:
if ( 'R' == name[0] != 'R')
I changed the above to read
Code:
if ( 'R' != name[0])
But the odd thing was that it worked differently depending on the platform it was compiled on. What does the ANSI C standard say? Could the gcc compiler have "optimized" this? I'm using various versions of gcc depending on the OS. I caught the bug on a Solaris 8 using gcc v3. Very odd that I should see different behavior on different platforms
ChrisA is offline   0 Reply With Quote
Old Aug 27, 2008, 06:43 PM   #2
TEG
macrumors 604
 
TEG's Avatar
 
Join Date: Jan 2002
Location: Langley, Washington
Send a message via ICQ to TEG Send a message via AIM to TEG Send a message via MSN to TEG Send a message via Yahoo to TEG Send a message via Skype™ to TEG
Quote:
Originally Posted by ChrisA View Post
I just fixed an obvious bug in a C program
Code:
if ( 'R' == name[0] != 'R')
I changed the above to read
Code:
if ( 'R' != name[0])
But the odd thing was that it worked differently depending on the platform it was compiled on. What does the ANSI C standard say? Could the gcc compiler have "optimized" this? I'm using various versions of gcc depending on the OS. I caught the bug on a Solaris 8 using gcc v3. Very odd that I should see different behavior on different platforms
The code you changed it to is correct C (at least as I have ever learned). The other one looks like old-style C, but doesn't make any sense. It is not really platfrom specific, but compiler specific. GCC compiles things differently than CC, gcc fixed some problems, while breaking some 'tricks' that programmers used.

C in general is not Platform specific, the compilers are, and have to do things differently for different platforms. So some things work on one platform, because of the age of the compiler, others don't because it is not implemented yet in another compiler. Same thing happens with the JVM, something will work on one platform, but won't on another because it hasn't had that piece implemented yet (common for programs written for JAVA Unix, and trying to run on Mac JAVA or Windows JAVA, even though Windows Java is done by the same company).

TEG
__________________
Apple and Dell are the only ones in this industry making money. They make it by being Wal-Mart. We make it by innovation, - Steve Jobs
The Tegian Zone-Glass Onion Radio

Last edited by TEG; Aug 27, 2008 at 06:50 PM.
TEG is offline   0 Reply With Quote
Old Aug 27, 2008, 07:28 PM   #3
ChrisA
Thread Starter
macrumors G4
 
Join Date: Jan 2006
Location: Redondo Beach, California
Quote:
Originally Posted by TEG View Post
The code you changed it to is correct C (at least as I have ever learned). The other one looks like old-style C, but doesn't make any sense.
No, not "old style C". X==Y!=Z is current valid ANSI syntax, but horrible style and should never be used. (it was a typographic error) But I thought for sure the result would be well defined by ANSI. I think it should be compiled as if written like (X==Y)!=Z Isn't the rule that if the operator president is equal then the expression is evaluated left to right?

Yes some things are different on diffract platforms. This software uses a GNU Autoconf script to look for that kind of stuff. But basic C language features one would think wold work the same.
ChrisA is offline   0 Reply With Quote
Old Aug 27, 2008, 07:41 PM   #4
lee1210
macrumors 68040
 
lee1210's Avatar
 
Join Date: Jan 2005
Location: Dallas, TX
Since != and == have the same precedence, we have to fall back to their associativity. In this case, it's right to left. So if we parenthesized your original statement it would be:
Code:
if ( 'R' == (name[0] != 'R') )
So first,
Code:
name[0] != R
would be evaluated. This would evaluate to 0 or 1 (sorry, I don't have the standard in front of me. I know for false it would be 0, and believe very strongly that true will evaluate to 1).

So next, either:
Code:
 'R' == 0
or
Code:
 'R' == 1
would be evaluated. This is where it gets tricky. The compiler will have to make an implicit cast as a char literal and the result of a boolean operator are not the same type. If 0 or 1 are cast to a char, then you are comparing:
Code:
 'R' == '\0'
or
Code:
 'R' == '\1'
This will always be false. However, if 'R' was cast to a "logical" (this isn't a type, but the compiler might be filling in some gaps for you) it is non-zero, so it would evaluate to true/logical 1. So then you would have:
Code:
 1 == 0
or
Code:
 1 == 1
So now this expression will evaluate to false/0 if name[0] != 'R' is false/0 or true/1 if name[0] != 'R' is true/1. In this situation, the statements would collapse to:
Code:
name[0] != 'R'
which is what you intended in the first place. Another option that I won't suss out completely is the compiler implicitly casting 'R' to an int, which would be 82. This compared to 0 or 1 would always be false just as if 0 or 1 were cast to a char.

Since I don't have the standard available I can't say which is "correct", but it may not be specified so this may be up to the interpretation of the compiler. The only time you would have gotten what you wanted was if, for logicals, the compiler tried to enforce != 0 strictly.

Such is the shortfall of a language without a boolean type.

Sorry this couldn't be more definitive, but hopefully it's at least somewhat enlightening in terms of the possibilities for the compiler's behavior. If you really want to see what gcc is doing, hand it a -S switch. I would try to isolate the offending code to make the resulting ASM easier to read.

-Lee

Last edited by lee1210; Aug 27, 2008 at 07:57 PM.
lee1210 is offline   0 Reply With Quote
Old Aug 27, 2008, 07:55 PM   #5
JVene
macrumors newbie
 
Join Date: Jul 2008
TEG is on point here.

My 2 cents.....

This looks like an edited fragment that really 'said' something else in some previous version, more like

if ( 'R' == name[0] && x[0] != 'R' ) ....

Of course, I'm inventing a proposed array x here to suggest there must have been something else on the mind of the writer at some point, where different tests were involved, and the '&& x[0]' was deleted without finishing through the second 'R'.

Now, the construct you have makes little sense to the compiler, because by the time 'it gets to' (we tend to anthropomorphize the machine don't we) the !=, the result of the first comparison (the ==) is a boolean, which can't promote to a value that correctly compares against an 'R'. That is, no result from the == test CAN compare to an 'R', so it will always be "!= 'R'" no matter how the first test came out - it will be true or false, comparing to a binary 0 or 1 in most compilers, but it could never be an 'R'.

There was a time when bool was not a 'formal' type in C. We often used some macro BOOL defined as an unsigned int or int, but it wasn't a 'built in' type. It has since become one, and so on different compilers the 'understanding' of the compiler differs. In all cases the result of the first == test is true or false, but if the built in type CAN'T be a bool, because the compiler is older and doesn't really 'think' in bools, it might not warn and the behavior might be errant.

On more recent compilers you will be warned, depending on your verbose settings, about the problem with the promotion. This can happen between compiler versions on the same platform (in line with TEG's point).

I bother to go this far to make a summary point. Portability is more important now than ever before. Whatever software we make, it is likely we'll have more customers if we consider portability when we write, and this kind of realization is exactly the stuff you have to think about when portability comes up - just what is common among the platforms and compilers, and which compilers should be choose to help portability.
JVene is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Very odd problem: Wifi speed issue with a specific network in specific part of room?! Arjun Jethwa MacBook Air 2 Jan 31, 2014 04:41 PM
Cross-platform apps Navdakilla Alternatives to iOS and iOS Devices 7 Dec 4, 2013 09:09 PM
What makes you switch from one platform to another ryanNL Alternatives to iOS and iOS Devices 12 Aug 21, 2013 09:33 AM
Which is the best cross platform for development? Wilbor9 iPhone/iPad Programming 6 Aug 6, 2013 07:09 AM
Which platform? chomer Mac and PC Games 8 Jun 21, 2012 04:18 AM

Forum Jump

All times are GMT -5. The time now is 10:19 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC