• Tim Gallagher (cs)
    Tim Gallagher:

    Moral of the story? Pogo was right. We have met the enemy and he is us.

    Not us as you in, but us as in me.

    ;) 

  • Dagon (cs)

    The first bit of code has a slight chance of being the result of somebody too addicted to editing videogames. Particularily, the game "Operation: Flashpoint" follows an almost identical syntax for its 'mini scripts' features.

    Either that or it's just coding even more backwards than Visual Basic is to begin with (an achievement with all but the most recent of versions <<).

    What the heck is going on in the second part of the code (besides a mess), anyway?

  • felix (cs) in reply to Dagon

    Spectrum Basic (and possibly other dialects) lacked an "else" construct. Maybe the author of the first sample is a dinosaur of the 1980es? 

    Dagon:


    What the heck is going on in the second part of the code (besides a mess), anyway?

    Is uses a little-known feature of the C preprocessor:

    "one can put several strings one after another"

    " like that"

    " and the compiler will see a long one instead."; 

    Quite useful sometimes, if you know about it. Only this guy found a C toolchain that isn't fully ANSI C. IMO, the WTF is bothering to support a non-standard implementation at all.

  • themagni (cs) in reply to Dagon

    Dagon:
    The first bit of code has a slight chance of being the result of somebody too addicted to editing videogames. Particularily, the game "Operation: Flashpoint" follows an almost identical syntax for its 'mini scripts' features.

    Either that or it's just coding even more backwards than Visual Basic is to begin with (an achievement with all but the most recent of versions <<).

    What the heck is going on in the second part of the code (besides a mess), anyway?

    Yeah, that first code falls under the "Unclear on the concept" category. Definitely weird.

    The second part is used for when you've got a few different options for compilation but you have a file that's almost identical. For example, if you have code that runs on two chips, but the pins are in different locations. You may also find it used for "portability" so that a windows-specific directive is only called when it's possible to accept it.

    It's also common practice in C and C++ to wrap all your .h files in


    #ifndef __FILENAME
    #define __FILENAME

    ... header file goes here

    #endif

    You do this because some compilers will try to include a file multiple times if you have #included it multiple times. You can end up with recursive compiles that take 30+ minutes to run. (This happened on a co-op job I did when I was in school. It was like that when I got there, and one time, the lead developer didn't even bother to compile before checking something in because it would have taken too long. Yes, it was wrong. Yes, I got blamed.)

    Anyway, what it seems like he's doing is putting out a notice when you're compiling to let you know which compiler you're using. There could be a justification for that, but I'm not sure what it would be. Perhaps alcohol was involved. The problem is that they aren't using the printf() function correctly, and that's what the problem is. It works in the second case due to a compiler-specific implementation, but from what I can see, there's no way the first implementation would ever work. Thus, they never ran it with the GCC configuration. So that means that they don't have automatic configuration worked out to make the precompiler directives work (i.e. the #ifdef loops are useless) and they don't know how to do it manually.

    It's late and I'm tired.  

  • Einsidler (cs)

    How the hell can someone not know how to use an ELSE?!?! I'm pretty sure I used VB elses on the first day I started programming.

     Some people really shouldn't be programming, or allowed out of the house unattented for that matter.
     

  • vk2tds (cs) in reply to Dagon

    WTF!

    You mean the GCC allows the line  ''printf("configuration: " CONFIG_STRING "\n");''?

    Darryl

  • Pseudonym (unregistered)

    The real WTF in the second snippet would be if the comment was actually correct.

  • The Idiot (unregistered) in reply to vk2tds

    Yes Virginia,  its called something like    concatenation of literal strings....  (This only works for LITERAL strings!)

     

    printf("HELLO " "CRUEL" "WORLD" "\n");

    and

    printf("HELLO CRUEL WORLD\n");

     

    should be 100% identical...   WHY?  Well try writing this in assembly.... "HELLO" will be one variable/array..  "CRUEL" will be the next...  What should go between "HELLO" and "CRUEL" in memory?  Why should you call several routines to read/copy each portion instead of one routine for the entire length?

    Other than a bit of extra work for the lexical parser,  this feature in C/C++ actually simplifies things...

     

    And in case you didn't catch it,  CONFIG_STRING is probably a macro that evaluates to a literal string...

  • EvanED (cs) in reply to Dagon

    Dagon:
    The first bit of code has a slight chance of being the result of somebody too addicted to editing videogames. Particularily, the game "Operation: Flashpoint" follows an almost identical syntax for its 'mini scripts' features.

    Either that or it's just coding even more backwards than Visual Basic is to begin with (an achievement with all but the most recent of versions <<).

     QBASIC had else blocks... I think... hmmm, now that I write that, I'm not sure. Anyone have better memory than I?
     

  • djc (unregistered) in reply to Dagon

    Dagon:
    What the heck is going on in the second part of the code (besides a mess), anyway?

    Most people would tend to just use commas between the args... 

  • missing (unregistered) in reply to themagni
    themagni:

    It's also common practice in C and C++ to wrap all your .h files in


    #ifndef __FILENAME
    #define __FILENAME

    ... header file goes here

    #endif

    You do this because some compilers will try to include a file multiple times if you have #included it multiple times. You can end up with recursive compiles that take 30+ minutes to run. (This happened on a co-op job I did when I was in school. It was like that when I got there, and one time, the lead developer didn't even bother to compile before checking something in because it would have taken too long. Yes, it was wrong. Yes, I got blamed.)

    All compilers should.  IIRC, Microsoft's got a #pragma once to change to nonstandard behavior, and GCC recognizes the #ifndef header guards.  It also protects you from the multiple definitions you'd otherwise get if you include the same file twice.  Recursive inclusion is far more rare.

    BTW, identifiers containing a double underscore (or a leading underscore followed by a capital letter) are reserved.  You should not use such names for your header guards.  I tend to just use FILENAME_H_INCLUDED.

  • EvanED (cs) in reply to themagni

    themagni:
    You do this because some compilers will try to include a file multiple times if you have #included it multiple times. You can end up with recursive compiles that take 30+ minutes to run.

    Or A includes B includes A loops.

    Or it gives you multiple definition errors depending on what's in your headers.

     
    As for the second example, I'm with the other posters in assuming that CONFIG_STRING is a preprocessor macro that expands to a string literal, in which case both cases should work. I don't particularily see it as a WTF even. I think it could have been done *nicer* with just a printf("configuration: %s\n", CONFIG_STRING) which as far as I can tell would have the same effect, wouldn't be really even the slightest bit confusing, and wouldn't have required an #ifdef, but in comparison with most of the code snippets on this site, it's pretty benign.
     

  • Ash (unregistered) in reply to EvanED
    EvanED:

    Dagon:
    The first bit of code has a slight chance of being the result of somebody too addicted to editing videogames. Particularily, the game "Operation: Flashpoint" follows an almost identical syntax for its 'mini scripts' features.

    Either that or it's just coding even more backwards than Visual Basic is to begin with (an achievement with all but the most recent of versions <<).

     QBASIC had else blocks... I think... hmmm, now that I write that, I'm not sure. Anyone have better memory than I?
     

    Yeah QBASIC did. F**k even my Sinclair ZX Spectrum did!
    Captcha: Batman
    How did it know who i was?!?
  • mAize (unregistered)

    You know, the second one is why people work as a team, so you can ASK for advice, rather than leave behind confusing comments than end up on the Internet, bringing in amusement and laughter to our miserable lives.
     

  • missing (unregistered)
    Tim Gallagher:

    Apparently, someone isn't familiar with the concept of an "Else" block.

    I've seen a similar construct from a very experienced, but somewhat goto-happy C programmer:

    if (condition)
      goto skip;
    /* no code here */
    if (another condition)
    {
      /* no code here */
    skip:
      a bunch of code;
    }


  • Blah (unregistered) in reply to djc

    I don't see what's so very bad about the second bit.  The second form would suffice for any compiler obviating conditional compilation, and there are other ways it could be done, but if that's the worst of your conditional compilation, be very thankful!

    I'm mostly impressed by the percentage of people who obviously know nothing about the intricacies of C but still feel compelled to post.

  • Cameron (unregistered) in reply to djc

    ... except that that doesn't actually work in C. The code in the 'WTF' is probably correct, although it'll break if CONFIG_STRING has a % character in it. A simpler work-around would have been printf("stuff: %s\n", CONFIG_STRING), of course.

  • Anonymous (unregistered) in reply to vk2tds
    vk2tds:

    WTF!

    You mean the GCC allows the line  ''printf("configuration: " CONFIG_STRING "\n");''?

    Darryl

    Yes.  It's string literal concatenation and according to GCC is part of ANSI C.  I'd link to an example in their documentation, but their online documentation doesn't appear to ever mention this, and as far as I can tell, the ANSI C specs aren't available online anyway.

    But supposedly it's standard behavior.  Stupid and dumb syntax, but standard behavior.

    But in any case, printf() shouldn't be used if you're not using any of the formatting features.  puts() exists for a reason.
     

  • EvanED (cs) in reply to Anonymous
    Anonymous:
    vk2tds:

    WTF!

    You mean the GCC allows the line  ''printf("configuration: " CONFIG_STRING "\n");''?

    Darryl

    Yes.  It's string literal concatenation and according to GCC is part of ANSI C.  I'd link to an example in their documentation, but their online documentation doesn't appear to ever mention this, and as far as I can tell, the ANSI C specs aren't available online anyway.

     They aren't. ISO and ANSI (& I think some random publisher) sell them. But believe the GCC standards; they're right. Here's the relevant section from the C++ standard:

     

    In translation phase 6 (2.1), adjacent narrow string literals are concatenated and adjacent wide string literals are concatenated. If a narrow string literal token is adjacent to a wide string literal token, the behavior is undefined. Characters in concatenated strings are kept distinct. [Example:
       
    "\xA" "B"
    contains the two characters '\xA' and 'B' after concatenation (and not the single hexadecimal character '\xAB'). ]

     (Section 2.13.4, paragraph 3; unchanged from the draft standard.)

     

  • blinkingtwelve (unregistered) in reply to The Idiot

    It seems to me that in assembly, these are zero-terminated strings. That sure would make a difference...

    blinkingtwelve

  • EvanED (cs) in reply to blinkingtwelve
    Anonymous:

    It seems to me that in assembly, these are zero-terminated strings. That sure would make a difference...

    blinkingtwelve

     The compiler removes the zero before concatenating them. Putting "abcd" "efgh" in your code is the same as using "abcdefgh", possibly modulo undefined effects like it affecting the address of the resulting string or whether two strings that are both "abcdefgh" are represented in one or multiple memory locations. But if you, say, use it as an argument to printf, both will print the same on any conforming implementation.

  • Dagon (cs)

    By backwards, I was meaning the nature of VB to code in in general (which is probably why it's generally relegated to a prototyping language, as it's easy to write protos in but very backward in various types of syntax, functions and constructs, not to mention high system overhead and other factors that make it less useful as a longterm project language).

  • Marc (unregistered) in reply to Anonymous

    But supposedly it's standard behavior.  Stupid and dumb syntax, but standard behavior.

     Neither stupid or dumb, but quite useful.   In the bad old days before ansi C one had no easy way to break up *long* literal string such that they were readable on display or paper.   Printers tended to truncate after column 132 or so.   Backslash newline combinations would always get lost in editing, causing cascading syntax errors at compile time.

    With compile time string concatination long literals could be written so:

        "The long string starts on this line "
        "and continues on this line "
        "and has even more text on this line, "
        "etc."

     Code that is easier to read is easier to debug, no?   This makes long literals easier to read.

    It's still a WTF, though.   String concatenation should have never been used in that situation for about eleventy-seven reasons.

    // marc
     

  • aikii (unregistered)

    The first code snippet looks like VERY old school BASIC ( when it was spelled in uppercase, like COBOL ... ). In those ancient time, an if could only execute ONE instruction, and ( if my memories are right ) there was no 'else'. if you need several instructions, you need a gosub or a goto, indeed. This is what happen in machine code anyway, but  programmers aren't machines, I guess ...

    But the real reason is certainly near Dagon's guess. There are many embedded application specific WTF-languages around here. This 'programmer' was probably a script-kiddie with a convoluted mind due to mirc scripting, the worst language I've ever seen. In 98 there was no loops, no local variables, no arrays, quite limited conditionnal statements, non-reentrant functions ( no local variable means no stack, indeed ... unless you hack one yourself ). Any non-trivial structure needed a goto. The best thing is that the parser's behaviour changed at each version, forget about backward compatibility of scripts. It's certainly more complete now, but I would be surprised if it became any better and non-WTFesque. I know several mirc-kiddies that became 'real programmers', and as I've seen their 'progress', my guess is that this one is one of those ...

  • Brendan (unregistered) in reply to Marc

    For the first one, it's he's fault for using VB.

    The second one. this reminds be of atoi topic. Not all implementations conform to the standard. For all we know the compiler could be a custom made compiler built for the company.

  • Dube (unregistered)
    Comment held for moderation.
  • Novus (cs) in reply to aikii
    Anonymous:

    The first code snippet looks like VERY old school BASIC ( when it was spelled in uppercase, like COBOL ... ). In those ancient time, an if could only execute ONE instruction, and ( if my memories are right ) there was no 'else'. if you need several instructions, you need a gosub or a goto, indeed. uess is that this one is one of those ...

    That's really old school. Even the Locomotive BASIC on the Amstrad CPC I started my coding career on in 1984 had ELSE. Also, both the THEN and ELSE branches could have multiple statements (separated by colons). However, the original Dartmouth BASIC (from 1964) seems to have an IF with no ELSE and a THEN clause that could only contain a line number to go to, which is even more limited (syntactially) than you say!

    Examples (Dartmouth (1964) and Locomotive (1984)):

    10 IF X+Y>0 THEN 410

    10 IF X+Y>0 THEN PRINT "FOO":A=0 ELSE GOTO 100

     

  • Omnifarious (cs)
    Tim Gallagher:

    Our second snippet comes from Mike who writes, "I know an intern was working on this code, but I'm afraid that it might not have been them that did this..."

    #if defined COMPILER_GCC
        printf("configuration: " CONFIG_STRING "\n");
    #elif defined COMPILER_XYZ
        /* XYZ doesn't seem to support concatenation like that */
        printf("configuration: ");
        printf( CONFIG_STRING );
        printf( "\n");
    #endif

    I find the fact that so many people are confused about the WTF here to be a WTF in itself. The code should read like this:

    #if !defined(STUPID_COMPILER)
       printf("configuration: " CONFIG_STRING "\n");
    #else /* You have a really stupid compiler that doesn't
             understand ANSI preprocessor string concatenation. */
        printf("configuration: ");
        printf( CONFIG_STRING );
        printf( "\n");
    #endif

    The basic problem is, what happens when you aren't using either GCC or the XYZ compiler? The preprocesor runs and the result is no code at all. All of the printf statements are completely eliminated. This is almost certainly not what was intended.

  • shinobu (cs) in reply to Marc

     

    "hello" " world"
    is legal C89/C99, while
    "hello " L"wide" " world"
    seems to be undefined in C89 but legal in C99

    ISO/IEC JTC1/SC22/WG14 - C

    See ISO/IEC 9899:1999 Working paper containing C99, TC1 and TC2 Section 6.4.5 "String literals". The "rationale for the C99 standard" contains some additional comments (section 6.4.5 as well). Some of these comments seem to be quite amusing:

    Those members of the C89 Committee who insisted that string literals should be modifiable were content...

    Do I see some sarcasm in between those lines? Anyway, there are some reasons why you would like to have them modifiable while there are other reasons why not. However would not matter that much, because programmers do not miss to write that const in front of char* p = "this is a string that will never be changed". Or do they? No way...

     

  • Anonymous (unregistered) in reply to themagni
    themagni:

    It's also common practice in C and C++ to wrap all your .h files in


    #ifndef __FILENAME
    #define __FILENAME

    ... header file goes here

    #endif

    Except that it's not legal. Identifiers that begin with a single underscore followed by a capital, or that contain a double underscore, or that begin with a capital E (as the errno constants) are reserved for the implementation (i.e. the system and standard header files). It doesn't matter that almost everyone does this. It's still not legal according to the C standard. An implementation, or a future version of the standard, could define __FILENAME to mean whatever it wants and break your code.

     

  • SilverDirk (cs) in reply to Marc
    Anonymous:

    But supposedly it's standard behavior.  Stupid and dumb syntax, but standard behavior.

    Neither stupid or dumb, but quite useful.
    ...
    Backslash newline combinations would always get lost in editing, causing cascading syntax errors at compile time.
    ...
    Code that is easier to read is easier to debug, no?   This makes long literals easier to read.
    ..
    It's still a WTF, though.   String concatenation should have never been used in that situation for about eleventy-seven reasons.
    // marc


    Dead-on.  (though some situations would justify its use here.  just not the use of printf)

    In addition, you can indent the strings, where the backslash/newline combo leaves an un-indented mess.  I still use the multiple string concatenation for the "Usage:" message for command line tools.

    puts("Usage: progname [options] arg0 arg1 arg2\n"
        "Where:\n"
        "\t-a = blah blah\n"
        "\t-b = blah blah\n"
        "\t-n = blah blah blah\n"
        "\targ0..2 = the name of the file to blah blah\n"
    );

    The above line results in a large string constant written out in a single series of bytes in the program's data segment.

    In Java, you would put a "+" between each of the strings.  This technically translates to a series of "append" method calls on an implicit StringBuffer.  Its up to your compiler to realize that the append operations are all performed on constant data, and that the whole of it can be replaced with a large string constant.
    Back in earlier C days, you definately wouldn't want to be relying on the optimizations of your compiler to prevent a bunch of runtime string concatenation.  (not that C had that ability anyway)


  • Omnifarious (cs) in reply to Omnifarious

    I probably ruined a whole bunch of people's fun watching so many forum participants stumble all over themselves saying all kinds of ridiculous things about the second code snippet. It's really sad when most of the WTF forum posters are no better than those who provide the main fodder for the articles.

  • SilverDirk (cs) in reply to Omnifarious
    Omnifarious:

    I find the fact that so many people are confused about the WTF here to be a WTF in itself. The code should read like this:

    #if !defined(STUPID_COMPILER)
    printf("configuration: " CONFIG_STRING "\n");
    #else /* You have a really stupid compiler that doesn't
      understand ANSI preprocessor string concatenation. */
      printf("configuration: ");
      printf( CONFIG_STRING );
      printf( "\n");
    #endif

    The basic problem is, what happens when you aren't using either GCC or the XYZ compiler? The preprocesor runs and the result is no code at all. All of the printf statements are completely eliminated. This is almost certainly not what was intended.

    Hey!  nice catch.  but you missed the printf != puts.  CONFIG_STRING might not have a '%' in it now, but no telling what people might add in the future.  Besides which, puts won't be doing a compare on each character to see if it is a '%' so there's a tiny speed increase.
  • Omnifarious (cs) in reply to SilverDirk
    SilverDirk:

    In Java, you would put a "+" between each of the strings. This technically translates to a series of "append" method calls on an implicit StringBuffer. Its up to your compiler to realize that the append operations are all performed on constant data, and that the whole of it can be replaced with a large string constant.

    Back in earlier C days, you definately wouldn't want to be relying on the optimizations of your compiler to prevent a bunch of runtime string concatenation. (not that C had that ability anyway)

    The modern C++ equivalent is adding together a series of ::std::string objects, which is generally handled less efficiently than Java's string concatenation of constant strings at compile time.

    Of course, the preprocessor string concatenation thing in no way relies on the compiler for its efficiency or to work at all. It is all done by the preprocessor before the compiler sees any of it. All the compiler itself ever sees is the string as one big chunk.

    Java doesn't have a preprocessor, so there is no place really where automatic concatenation of adjacent constant strings can happen. (Though it is a fairly simple syntax rule, and you could just define a string constant to allow arbitrary whitespace between quoted sections.) So the '+' operator is used and the compiler is relied upon to make this efficient.

  • Hans (unregistered)

    In my first job, I worked for a company that did all their work in Pascal. I found a rather weird pattern repeated everywhere, and upon asking, was told that these were written by the owner of the company (back when he still wrote code). Since the man is a reputed genius, obviously there cannot be nothing wrong with it...The pattern is as follows (translated to C++ because I cannot remember Pascal syntax now...):

     

    int x;

    bool first = true;

     for (x = 0; x<10; x++) {

        if (first) {

            // Do all loop initialisation here.

            first = false;
        } 

        // Normal loop body goes here. 

    }

    Notice anything slightly unusual?

     

     

     

  • Omnifarious (cs) in reply to SilverDirk
    SilverDirk:

    Hey!  nice catch.  but you missed the printf != puts.  CONFIG_STRING might not have a '%' in it now, but no telling what people might add in the future.  Besides which, puts won't be doing a compare on each character to see if it is a '%' so there's a tiny speed increase.

    Oh! Oops, you're right. *sheepish grin*

    #if !defined(STUPID_COMPILER)
        puts("configuration: " CONFIG_STRING); /* puts appends a newline */
    #else /* You have a really stupid compiler that doesn't
             understand ANSI preprocessor string concatenation. */
        printf("configuration: %s\n", CONFIG_STRING);
    #endif

    You could use fputs and puts in the second case, but I think that would be kind of obscure for little benefit. Additionally, the #else section has the nice benefit of explaining the #if section for people who don't know about ANSI preprocessor string concatenation, which is apparently quite a few people.

  • SomeDude (unregistered)

    (irrelevant code removed):"

    If {condition} Then
    ' ...code here
    Goto skipIt
    End If
    ' ...more code here
    skipIt:

    Apparently, someone isn't familiar with the concept of an "Else" block."

    ---------------


    Maybe some relevant code was removed after all. If this is code snippet was found in a WHILE loop, the 'Goto skipIt' may well have been there due to the lack of a 'continue' statement in VB.

  • qbolec[bad English] (unregistered) in reply to Omnifarious

    Well, I found it stupid to optimize a fragment of code that is supposedly run only once. What is the gain of using compiler-specific puts("A" "B") instead of printf("A %s\n","B"); when it's called only to show configuration?

    And probably he didn't use #else for some reason (maybe other compilers do not bother to define CONFIG_STRING at all).

    And yes, string concatenation is quite usefull for long strings spanning across several lines.

    And yes, using unknown string for a format is illegal in several countries, although I wouldn't expect the compiler to perform buffer overruns to hack it's own code.

     

     

  • leeg (unregistered) in reply to Anonymous
    Anonymous:
    themagni:

    It's also common practice in C and C++ to wrap all your .h files in


    #ifndef __FILENAME
    #define __FILENAME

    ... header file goes here

    #endif

    Except that it's not legal. Identifiers that begin with a single underscore followed by a capital, or that contain a double underscore, or that begin with a capital E (as the errno constants) are reserved for the implementation (i.e. the system and standard header files). It doesn't matter that almost everyone does this. It's still not legal according to the C standard. An implementation, or a future version of the standard, could define __FILENAME to mean whatever it wants and break your code.

     

     
    IME, it's more common to see _FILENAME_H_ used as the guard.  Except that I'm an Objective-C programmer so I just use #import and have done with it ;-)
     
    #import is like gcc's #pragma once, except it's not deprecated.  I believe there's an edge case where the same file is hard-linked to different paths and it could then be #imported twice, but that's somewhat unlikely.
     
    captcha: clueless 
  • qbolec[bad English] (unregistered) in reply to leeg

    #import is also a valid keyword in dev-cpp, so it's probably valid in every g++-like compiler

  • Crate (unregistered) in reply to Omnifarious
    Omnifarious:

    I find the fact that so many people are confused about the WTF here to be a WTF in itself. The code should read like this:

    #if !defined(STUPID_COMPILER)
    printf("configuration: " CONFIG_STRING "\n");
    #else /* You have a really stupid compiler that doesn't
    understand ANSI preprocessor string concatenation. */
    printf("configuration: ");
    printf( CONFIG_STRING );
    printf( "\n");
    #endif

    The basic problem is, what happens when you aren't using either GCC or the XYZ compiler? The preprocesor runs and the result is no code at all. All of the printf statements are completely eliminated. This is almost certainly not what was intended.

     

    Why?

    Wouldn't this do: 

        printf("configuration: ");
    printf( CONFIG_STRING );
    printf( "\n");
    no matter what compiler...? 

     

  • Tim (unregistered) in reply to Omnifarious
    Omnifarious:

    I probably ruined a whole bunch of people's fun watching so many forum participants stumble all over themselves saying all kinds of ridiculous things about the second code snippet. It's really sad when most of the WTF forum posters are no better than those who provide the main fodder for the articles.

    You're right about that :-).  I think my boggle-o-meter exploded when someone suggested that printf will produce output while compiling

    And what is the deal with so many people not knowing about literal string concatenation?  I don't know, kids today, etc.

    (btw, aside from readability, string concatenation is very useful when trying to embed \x sequences into string literals.) 

  • jimlangrunner (cs) in reply to felix
    [image] Felix:
    Spectrum Basic (and possibly other dialects) lacked an "else" construct. Maybe the author of the first sample is a dinosaur of the 1980es?
     

    Ooh!  Let me.  Business Basic, the language of the ages, has been evolving for years.  (Go ahead.  I'll wait.) So when I started my current job, I was reviewing the code that went before me to sort of learn the lay of the land.  I came across this little gem:

    0220 IF K$(9,1)<>"Y" THEN LET Q$=K$(10,3),A=NUM("A",ERR=0310)

    Now, for those not familiar, the highly favored "GOTO" statement did not exist in early versions of Business Basic, so programmers found all kinds of interesting ways to get around that shortcoming.  Nevermind that all variables are global....

    Yes, the language still exists, but it's java-based (believe it).  We dumped it for VB several years back, but must still support 'way too many folks for a while yet.  Until I quit. I can't wait.

  • KoFFiE (cs) in reply to Crate
    Anonymous:
    Omnifarious:

    I find the fact that so many people are confused about the WTF here to be a WTF in itself. The code should read like this:

    #if !defined(STUPID_COMPILER)
    printf("configuration: " CONFIG_STRING "\n");
    #else /* You have a really stupid compiler that doesn't
    understand ANSI preprocessor string concatenation. */
    printf("configuration: ");
    printf( CONFIG_STRING );
    printf( "\n");
    #endif

    The basic problem is, what happens when you aren't using either GCC or the XYZ compiler? The preprocesor runs and the result is no code at all. All of the printf statements are completely eliminated. This is almost certainly not what was intended.

     

    Why?

    Wouldn't this do: 

        printf("configuration: ");
    printf( CONFIG_STRING );
    printf( "\n");
    no matter what compiler...? 

     



    That would be 3 function calls instead of a single... The WTF in combination with what Omnifarious is saying is that there are C compilers not supporting this kind of concatenation. Even in my 7-year of embedded C development and a lot of obscure C compilers, I never encountered one which doesn't support this basic feature... Anyone any idea about which compiler was used? :)
  • Merlin (unregistered)

    I once met a programmer that was writing some of those "if goto next". It took me one whole hour to get him to understand that his:

    if (cond) {
        goto skipit;
    }
    else {
        some code over here...
        ...
    }
    skipit:

    Was exactly equivalent to the much simpler:

    if (!cond) {
         some code over here...
        ...
    }

    The last time I heard about the guy, he was working at an ISP helpdesk...

     

  • Kerry (unregistered) in reply to Hans
    Anonymous:

    In my first job, I worked for a company that did all their work in Pascal. I found a rather weird pattern repeated everywhere, and upon asking, was told that these were written by the owner of the company (back when he still wrote code). Since the man is a reputed genius, obviously there cannot be nothing wrong with it...The pattern is as follows (translated to C++ because I cannot remember Pascal syntax now...):

     

    int x;

    bool first = true;

     for (x = 0; x<10; x++) {

        if (first) {

            // Do all loop initialisation here.

            first = false;
        } 

        // Normal loop body goes here. 

    }

    Notice anything slightly unusual?

     

    This construct is not all that uncommon.  But "first" needs to be defined as a non-stack based variable (static, etc) or it will be initialized to true every time.

  • Anonymous Coward (unregistered)

    Any standard implementation of printf should produce the desired result without the need to call printf thrice regardless of concatenation support:

     printf("configuration: %s\n",CONFIG_STRING);


     

  • Xarium (cs)

    This is pedantic, I know, I'm sorry, but I can't put up with the compiler versus pre-processor being mixed-up for any longer...

    The C-preprocessor does not do any string concatenation.

    Any concatenation that occurs is the compiler not the preprocessor.

  • anonymous (unregistered) in reply to vk2tds
    vk2tds:

    WTF!

    You mean the GCC allows the line  ''printf("configuration: " CONFIG_STRING "\n");''?

    Darryl

    I love how elegant is C:

    THANKS GODS C IS NOT DELPHI: 

    if ( whatever) then

    begin

       foo();

    end; 

    THANKS GODS IS NOT BASIC:

    If condition Then
     Foo; 
    End If
    C IS SIMPLY RIGHT: 

     if ( condition ) foo();

    or

    if (condition) {
      foo();
    }

     

     

  • TickleMeElmo (cs) in reply to Anonymous Coward
    Anonymous:

    Any standard implementation of printf should produce the desired result without the need to call printf thrice regardless of concatenation support:

     printf("configuration: %s\n",CONFIG_STRING);

     
    That's definitely the best approach so far. The only reason to jump through any fancy preprocessor hoops would be if there were a large performance gain to be had. This looks to be just writing diagnostic output, likely low volume.

    The real issue here is a pretty common one -- developers' fear of changing anything that they didn't write themselves. It's common and usually baseless. Step up, take ownership, and make it better!


Leave a comment on “We Have Met the Enemy”

Log In or post as a guest

Replying to comment #:

« Return to Article