More API madness

Discussion in 'SolidWorks' started by Jim Sculley, Mar 2, 2004.

  1. Jim Sculley

    Jim Sculley Guest

    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.
     
    Jim Sculley, Mar 2, 2004
    #1
  2. Jim Sculley

    Heikki Leivo Guest

    If only it were TRUE. Or is that VARIANT_TRUE?
    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
     
    Heikki Leivo, Mar 2, 2004
    #2
  3. 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
     
    Corey Scheich, Mar 2, 2004
    #3
  4. Jim Sculley

    Jim Sculley Guest

    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.
     
    Jim Sculley, Mar 2, 2004
    #4
  5. Jim Sculley

    InsideInfo Guest

    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.
     
    InsideInfo, Mar 2, 2004
    #5
  6. Jim Sculley

    TheTick Guest

    Much of my API knowledge seems to have been derived from "Why doesn't
    it do what the doc says" experiments.
     
    TheTick, Mar 3, 2004
    #6
  7. Jim Sculley

    Heikki Leivo Guest

    Interesting coincidence, I discussed this true/false subject earlier
    today
    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-
     
    Heikki Leivo, Mar 3, 2004
    #7
  8. Jim Sculley

    Jim Sculley Guest

    Until you make a mistake such as:

    #include <stdio.h>

    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.
     
    Jim Sculley, Mar 3, 2004
    #8
  9. Jim Sculley

    Heikki Leivo Guest

    Heikki Leivo wrote:
    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-
     
    Heikki Leivo, Mar 3, 2004
    #9
  10. Jim Sculley

    Jim Sculley Guest

    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.
     
    Jim Sculley, Mar 3, 2004
    #10
  11. Interesting discussion, indeed.
    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
     
    Corey Scheich, Mar 3, 2004
    #11
  12. (I meant to say this code would be run)
     
    Corey Scheich, Mar 3, 2004
    #12
  13. Jim Sculley

    Heikki Leivo Guest

    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-
     
    Heikki Leivo, Mar 3, 2004
    #13
  14. 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.
     
    Corey Scheich, Mar 3, 2004
    #14
  15. Jim Sculley

    Jim Sculley Guest

    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.
     
    Jim Sculley, Mar 3, 2004
    #15
Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments (here). After that, you can post your question and our members will help you out.