Anyone know about this random little feature of C?

Started by
37 comments, last by CJM 19 years, 1 month ago
Found this out at university today, not one of the lecturers knew about it, nor the tutors (one of the students did it in a tutorial) anyway, this is completly valid code in C/C++:

printf("how"
       "are"
       "you?");
C concats the strings automagically for you. so;


void doStuff(char * text)
{
    // blag
}

void main()
{
   doStuff("I" "am" "fine");
}

is also fine. Weird huh? maybe it's just me, but to me, thats really really bad, the compiler effectivly changes your code.
Advertisement
Well think about what you are saying there.

Your memory locations will look something like this (Char* purechar Char* purechar Char* purechar )

None of those has a \0 on the end of it so it'll read til it doesn't find characters any more. So it skips to the second group of characters. Does it output "Iamfine" or does it output it with spaces?

Remember the compiler never officially changes your code, it just interprets it, and if this functionality is in here (and it appears to be) it was supposed to be here, especially in something so overly used as printf.
I use that feature frequently for long constant strings. I hate having my constant messages stretch right off the side of the screen so I do that. ;)
And like was said before thats how the compiler interprets it. It is just a long string. If you put ,'s or ;'s in between then it would be interpreted differently.
I knew about that. I think it's great for breaking apart long lines, to keep the code neat and readable. Don't remember how I first found out about it though.

Then again, I haven't really used it since I started using C++ streams, I just do something like this:

cout << "I"
<< " am "
<< " fine " << endl;

In order to break up any long character strings and keep things readable.

Fun stuff!
Quote:Original post by RipTorn
maybe it's just me, but to me, thats really really bad, the compiler effectivly changes your code.

I'm not sure why you think it changes your code; it's just a feature of the laguage like anything else, you just haven't run into a good use for it yet. Most-commonly, you'll only be using it on either really long strings that would extend very far on one line, or if you are working with the preprocessor and want to concatenate two strings together. One quick example use would be:

#include <iostream>#define ERROR_MESSAGE( error_message ) "Error: " #error_message int main(){  ::std::cout << ERROR_MESSAGE( divide by zero );  // Same as  ::std::cout << "Error: divide by zero";}


Quote:Original post by RipTorn
void main(){   doStuff("I" "am" "fine");}


is also fine.

Actually that is not fine, since void main is neither valid C nor C++. The main function must have the return type int in C and C++ (though many non-compliant compilers support void main, it is not standard).
It's not weird at all, it's pretty useful in fact and is fairly widely used. I'm surprised nobody at your university had seen it before. It's particularly useful for doing something like this:

const char* helpText = "This is some multi-line help text that you wouldn't want to squeeze onto one \n""line in the source code. Think about how you'd have to lay out a string like this \n""if C/C++ didn't support automatic concatenation of string literals. The concatenation \n""happens at compile time, not at runtime, so the compiler isn't changing your code at \n""all, it's just saving you from having lines hundreds of characters long in your source. \n";

Game Programming Blog: www.mattnewport.com/blog

I use it a occasionally. It is handy for building strings with macros. Saying the the compiler changes your code is not correct, since putting two strings together like that tells the compiler to concatenate them.

The only drawback is that bugs like this happen a lot:
char * array[] ={    "1",    "2",    "3",    "4"    "5",    "6"}; 
The above array has only five elements. Oops.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
Quote:Original post by Polymorphic OOP
Actually that is not fine, since void main is neither valid C nor C++. The main function must have the return type int in C and C++ (though many non-compliant compilers support void main, it is not standard).
Legality of void main().
I just felt like counter-nitpicking..
Quote:Original post by cgoat
I knew about that. I think it's great for breaking apart long lines, to keep the code neat and readable. Don't remember how I first found out about it though.

Then again, I haven't really used it since I started using C++ streams, I just do something like this:

cout << "I"
<< " am "
<< " fine " << endl;

In order to break up any long character strings and keep things readable.

Fun stuff!

Not that this is something that really needs optimizing but still, using streams for this is horrendously inefficient by comparison since string literals are concatenated by the compiler at compile time and so there is no runtime cost whereas doing it this way requires a function call for every concatenation.

Game Programming Blog: www.mattnewport.com/blog

I didn't mean to imply that the iostreams were better or anything... just a comment on how I hadn't used that particular language feature since starting to use iostreams more often.

This topic is closed to new replies.

Advertisement