More API madness

Back on 02/06 Heikki Leivo had this to say in a thhread about the poor state of the API and its docs:

"Well, hmm, maybe you should not take it granted that the return value actually means something... :-P"

I chuckled to myself at that, but now I see that it isn't far off the mark. Consider the SldWorks::get_Visible() function. The API docs state:

Syntax (Com)

status = SldWorks->get_Visible( &visibility )

status = SldWorks->put_Visible( visibility )

Property: (VARIANT_BOOL) visibility TRUE if the application is visible, FALSE if not

Return: (HRESULT)status S_OK if successful

An innocent looking description, very straightforward. Let's dig deeper.

VARIANT_BOOL is defined as a data type that should be one of two values. Those values are VARIANT_TRUE or VARIANT_FALSE, which map to 0xffff and 0x0000 respectively. In bits, that's all ones or all zeroes.

If one assumes that SW follows the rules for VARIANT_BOOL, then one would assume that the API docs above should say VARIANT_TRUE and VARIANT_FALSE, instead of TRUE and FALSE. After all, professional programmers know this stuff, but documentation writers often don't. The API is littered with copy/paste errors such as this.

This is the way I approached such API functions in the past. "It must be a typo in the docs", I said.

Sadly, today, I discovered the opposite. When the API docs say that the function returns TRUE or FALSE, they mean it. "Fine," you say. "Big deal. How much difference can there be between TRUE and VARIANT_TRUE anyway? They are probably equivalent in everything but name. You're making a mountain out of a molehill".

If only it were TRUE. Or is that VARIANT_TRUE?

You see, TRUE is represented by 0x01, which is markedly different from

0xffff. In decimal, these are 1 and -1 respectively.

It is frightening to me to see such a glaring problem in the published API. Typically, the API is the cleanest because it is what the customer sees. Lots of ugly things happen behind the scenes, but always a pretty face up front.

Now I must be suspicious of everything.

Jim S.

Reply to
Jim Sculley
Loading thread data ...

Interesting coincidence, I discussed this true/false subject earlier today with my friend. You should keep in mind, that in computer programming (especially on hardware level!) boolean FALSE is defined as zero, and TRUE is defined as _any non-zero value_, including 0x01. In Visual Basic (and apparently in specification for variants in COM interface) "True" is defined as -1, which is 0xFF, only to ensure that "Not TRUE" equals "FALSE". Any other non-zero values are "True", too, and it is not illegal in any way, yet maybe unethical. You should keep in mind, that NOT operator is always bitwise, and IF statements work always so that zeroes are FALSE and any other values are TRUE. So in my opinion SW api doesn't do anything "wrong" in this case, but it is of course acceptable to expect some common sense from the API.

Some years ago I was having similar problems with a certain SW API function call (related to stereo api, IIRC). I had an If statement such as "If Not Foo Then..." in my code, and the if statement was never executed even though the value of the variable being tested seemed to be True when debugging the code. I asked API support what the heck was going on, and they explained the fact mentioned above. Since that I have been avoiding Not operator in If statments.

Are you testing the return values like "If(Foo == VARIANT_TRUE){...}"? You could use syntax like "If(Foo){...}" instead, because if statement interpretes any non-zero values as TRUE. Because of the bitwise nature of NOT operator, one should never use if statements like "If(Not Foo){...}". Not False is always True, but Not True may be either True or False, and it is absolutely normal! You just have to cope with that. :-P

Hope this helps!

Kind regards, Heikki

Reply to
Heikki Leivo

Very clear explanation. Thank you for that, it is always nice to hear in plain english why it could cause a problem to use something so basic as the Not statement.

Corey

Reply to
Corey Scheich

So that's why my IF statements act so wierd.... Thanks.

Reply to
Dale Dunn

Not true. No pun intended. At the hardware level perhaps, but programming languages have (or should have) evolved beyond this. Java defines the boolean as an actual primitive. It can be only 'true' or 'false'. Code such as:

int x = 32; if (x) { //do stuff }

won't even compile in Java.

No they are doing something wrong. They return 1, when the only acceptable values are -1 and 0 according to the specification for the type they have chosen to use (VARIANT_BOOL). All thew API docs do is provide evidence of their crime so to speak.

Which allows the following silliness:

if (retval != VARIANT_TRUE && retval != VARIANT_FALSE) { printf("An illegal error occurred. This error is not allowed...); }

No I don't. I simply have to port the API to Java where the not operator always behaves as it should.

;)

Jim S.

Reply to
Jim Sculley

The safest way actually is to check for the reverse of the FALSE condition (since VARIANT_FALSE and FALSE are the same), rather than using VARIANT_TRUE / TRUE conditions.

-InsideInfo.

Reply to
InsideInfo

Much of my API knowledge seems to have been derived from "Why doesn't it do what the doc says" experiments.

Reply to
TheTick

Heh. However, in this case, it does *exactly* what the docs say, but it shouldn't.

Jim S.

Reply to
Jim Sculley

Why should they have evolved? In my opinion there is nothing wrong in the definition of True and False. You just have to know it, and everything works perfectly. In my opinion, BOOLEAN data type expects only that the value doesn't contain any other useful information.

Booleans would be indeed easy to understand, if boolean values were single BITS. Modern computers cannot, however, handle single bits! If I remember correctly, 32-bit processors cannot fetch less than 4 bytes (32 bits) of data from memory. Therefore booleans are always rather huge pieces of data, even though they are defined to contain only true/false information. In my opinition the programming languages shouldn't evolve so far that the programmer forgets what he is actually doing - programming the hardware. But, it is just my opinion, and you don't have to agree. :-)

Java syntax has evolved from C, and I just don't believe this, because it would be soooooooo wrong! If this is True (eg. Not False), I will never move to Java. Horrible. For example, consider the VB InStr function: InStr(1, "abcde", "c") returns 3 (which is True), ie. the position of "c" in string "abcde". If "c" is not found, the function returns 0 (=false). You can use the instr function to test whether certain string is found inside another string. Therefore you can use the function in an if statement like "If InStr(Foo,Bar) Then...". Hovever, if the if statement would accept only "boolean" values, you should write more complex code to test the condition.

gotta go now, I will continue later.

-h-

Reply to
Heikki Leivo

Until you make a mistake such as:

#include

int main() { int x=2; if (x=3) { printf("x is 3"); } else { printf("x is %i", x); } }

C:\Temp>test.exe

x is 3

'If' statements that accept any integer value are dangerous.

In Java, for all intents and purposes, they are single bits. How the machine represents them is irrelevant, because it is hidden from you.

And I don't. :P The beauty of Java is that you aren't programming the hardware. You are programming the virtual machine which has well defined semantics, no undefined behavior, and very few surprises.

Vastly improved from C in most areas. Sadly not improved in other areas (such as the 'switch' construct).

public class BelieveIt { public static void main(String[] args) { int x = 32; if (x) { //do stuff } } }

C:\Temp>javac BelieveIt.java

C:\TEMP\BelieveIt.java:4: incompatible types found : int required: boolean if (x) { ^

1 error

Why? The idea of a boolean is to be either true or false. Anything else is nonsense. It is like walking up to someone and saying:

"True or false: The year is 2004"

and the person answers

"Green".

The 'if' statement accepts any *expression* that evaluates to a boolean:

if (theSkyIsBlue() && theGrassIsGreen() && isWeekend()) { doStuffOutside(); } else { getBackToWork(); }

Why? The equivalent Java code is:

if (str.indexOf("c",0)) > 0) { // do stuff } else { //do other stuff }

Strings are objects in Java, just like everthing else, so they have methods you can call, such as indexOf.

Note that indexOf is a much better name for this function than InStr as well. It is clear from the method name that it returns the index of the specified String. If I were reading code and didn't know what InStr did, I would likely assume that it simply told me if a string contained another string. The fact that it returns the index of the string isn't obvious.

Jim S.

Reply to
Jim Sculley

Interesting discussion, indeed.

Well, mistakes are mistakes and bugs are bugs. If statement works perfectly right here, since If statement accepts any _expression_ to be evaluated, and _statements_ are _expressions_. The value of statement "x=3" is 3, which is TRUE. IMO this is very basic stuff and should be explained in every programming course, including the difference beetween comparison and assignment operators.

You may end up in catastrophical result as well, if you accidentally step on the gas pedal instead of brake, but it is rather difficult to prevent.

Well, this is bit like a religional subject; we don't seem to share the same opinion here, but neither of us is absolutely right here.

Again, the validity of the answer depends on how the "true" and "false" are defined. In programming, "Green" would be "true", since it is not zero.

Perfectly right, but Java seems to do a huge exception here by having a different definition to boolean values.

Well, I didn't specify how much complex... :-P

And... ta-dah, the function IS telling exactly whether or not a string is contained inside another (since non-zero values are TRUE), PLUS as extra feature it returns the character position of the first occurence of the found sub-string.

In my opinion, it is absolutely right that the function names should be obvious, but the documentation is always there to help you if you miss something.

And then there are these wonderful newsgroups!

-h-

Reply to
Heikki Leivo

No, it's 3. Three is neither true or false. It is simply 3. Have you ever answered '3' on a true/false exam? I prefer to not have to alter my view of the universe just because I want to write some code.

I consider any help the language/compiler can give to prevent bugs (whether logical or typographical) to be useful.

The lack of a true boolean type is the source of the problem I described in the first post of this thread. It is perfectly reasonable to expect TRUE, VARIANT_TRUE or any boolean expression whose value is true to be interchangeable, regardless of the construct in which they are used. Why should FALSE, VARIANT_FALSE, et. al. have this quality, but not TRUE and VARIANT_TRUE?

The fact that a snippet such as:

if (VARIANT_TRUE == TRUE) { printf("No problem"); } else { printf("Problem"); }

prints:

Problem

bothers me.

The problem under discussion, however, is trivial to prevent. See Java. At the very least, as a courtesy, values such as VARIANT_TRUE should not be -1 while TRUE is +1.

You're just saying that because you are wrong. ;)

You say 'programming' as though it is a universal constant.

Only in a language not smart enough to have a true boolean type. :P Imagine if you went through life following all the silly little rules that some programming langauges make you remember.

Java's 'different' definition is the correct definition. The problem I encountered in my original post can never happen in Java.

Extra features have no business in code. They lead to obfuscation. They are almost as bad as side effects. Call a function to make a beep, and as a side effect, your monitor turns off.

If you think Java is strange, Smalltalk would likely make your head explode:

(anInteger > 10) ifTrue: [ "code for true case" . . . ] ifFalse: [ "code for false case" . . . ].

;)

Jim S.

Reply to
Jim Sculley

Jim I have to agree with Heikki on this point. In an if statement (x=3) is a comparison it returns True if x has a value of 3 and False if x has any other value. Here is another way to explain it

Dim x as long

x = 2

If x =3 then (this code would be skipped end if

' in the case above x=3 would return False because the variable x is set to

2 and 2 does not equal 3

Dim x as long

x = 3

If x =3 then (this code would be skipped end if

' in the case above x=3 would return True because the variable x is set to

3 and 3 equals 3

basically the If statement is asking the question does the variable x equal

3 if yes(true) continue if no(false) skip.

Just trying to be objective.

Corey

Reply to
Corey Scheich

(I meant to say this code would be run)

Reply to
Corey Scheich

Corey,

The point here was, that in C and Java there is assignment operator (single =) and comparision operator (double ==). Therefore, x = 3 does not test whether x equals 3, but instead it assigns value 3 to variable x. This is a common mistake; when testing there should be x == 3, which is a common typo. What is most peculiar, the syntax in "If(x = 3)" is correct, and causes no errors in compiling. The reason is, that in C the "statements" (which _do_ something) are "expressions" (which _express_ a value). A simple rule states, that the value of any "statement" is the value of the rightmost expression inside the statement. Therefore, the statement "x = 3", which assigns value 3 to x, is equal to 3, which is the rightmost expression in the statement. In C and Visual Basic the If statement tests whether the "expression" being evaluated is either zero or non-zero. Non-zero values are treated as "True", and therefore the missing "=" results in weird behaviour.

I don't see any problems in understanding and accepting this; if "true" is defined such a way, so what - let it be. But I understand, too, that Jim has a different opinion. To be exact, we were not talking about the very same subject: Jim was talking about the "real world" trues and falses, which of course can be only true/false, but I was talking how they are actually implemented in C, VB and lots of other programming languages. It is a pure opinion if the common way how boolean data types actually work is considered to be somehow "wrong", and if it works "better" in some certain programming languages.

-h-

Reply to
Heikki Leivo

It has been a while since I had done any C programing and I didn't do much then I had forgotten that it would have to be a double == forgive me. Carry on.

programming

Reply to
Corey Scheich

You get weird behavior for zero values as well. Something like this can occur fairly easily:

int x = 0; //... //Lots of code that fiddles with x //...

if (x=0) { //Oops. }

Which apparently don't map well to the real world. ;)

I consider the implementation of boolean values in C and such to be a logical hole in the language. A computer langauge shouldn't cause you to scratch your head and say 'Huh?".

Jim S.

Reply to
Jim Sculley

PolyTech Forum website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.