why the code using serial.println compiles without serial.begin?

hello!

i observed that if i comment out the "serial.begin(baudrate);" line, and there are still "serial.println();" lines in my code, it compiles without any errors / warnings. how is this possible?

the serial.begin command is not mandatory for the ide to set the baud rate, etc? what baud rate is used if this command is omitted?

what happens from the performance point of view? if i comment out the serial.begin command, but i leave several serial.println, my code will run slower?

thanks!

It is mandatory. The lines simply will not do a thing. So it will not run slower then with serial.begin() in it. But I think (not 100% sure) calls to a print statement will still fill the serial buffer. Aka, as long as you use a print statement it will still take up space and time compared to not having any Serial calls.

It compiles without error because the compiler does not look at what a specific function does. It just compiles what it needs to do. So it cannot give an error if you didn’t call serial.begin(). Maybe you do this on the fly in loop? Or in a library? etc.

Serial.begin and Serial.println are just functions like any other that you make. The compiler doesn't have any knowledge of something that high level, it just translates the programming statements to machine code. println is completely independent from begin, so the compiler can make valid code for each.

The begin function initializes the UART hardware. If it isn't included, that won't stop println from compiling, but it means the code will not operate the way you intend.

"Yellow is a hateful shoe, but I would like to smell jealousy" is a valid sentence, syntax-wise. Nouns, verbs, and punctuation are all in the right place. You could give that sentence to a translator and they could probably translate it into a foreign language sentence with equally valid syntax.

Valid syntax doesn't stop it from being nonsense semantically. What does it mean for a color to be a "hateful shoe"? How can you smell an emotion?

Code is the same way. The compiler can only catch syntax errors that violate the rules of the language, such as misaligned brackets or keywords in places they shouldn't be. The compiler has no higher level understanding of semantics though. It's not made to know about semantic dependencies between functions like that.

Compilation can only catch syntax errors. To find semantic errors, you have to actually run the code and see if it works right.

thank you guys, for the prompt reply! it makes things much clearer now.

so, if i comment out just the serial.begin line, it will not speed up my code…
but while testing / debugging, it is very annoying to always search for and uncomment / comment all the serial.print lines in a longer sketch.

there is an automatized way to switch between production version and debugging version?
somehow, for example, if i set a bool to true at void setup(), then use the serial.print lines, and if i set to false, ignore them?

#define MY_DEBUG //comment to not run debug

#ifndef MY_DEBUG
  #define DEBUG_PRINT(x)
  #define DEBUG_PRINTLN(x)
  #define DEBUG_PRINT(x,y)
  #define DEBUG_PRINTLN(x,y)
#else
  #define DEBUG_PRINT(x) Serial.print(x)
  #define DEBUG_PRINTLN(x) Serial.println(x)
  #define DEBUG_PRINT(x,y) Serial.print(x,y)
  #define DEBUG_PRINTLN(x,y) Serial.println(x,y)
#endif

DEBUG_PRINT("Will only print if MY_DEBUG is defined");

...hm, very interesting idea. i will #define TLY try it :slight_smile:

thanks!

wanek:
i observed that if i comment out the "serial.begin(baudrate);" line, and there are still "serial.println();" lines in my code, it compiles without any errors / warnings. how is this possible?

Basically - you are smarter than the compiler. The compiler mechanically converts line by line into machine code, and does a great job of that, but it's the programmers job to understand the overall picture of what is happening.

Ow, and I forgot a form for begin.

#define MY_DEBUG //comment to not run debug

#ifndef MY_DEBUG
  #define DEBUG_BEGIN(x)
  #define DEBUG_PRINT(x)
  #define DEBUG_PRINTLN(x)
  #define DEBUG_PRINT(x,y)
  #define DEBUG_PRINTLN(x,y)
#else
  #define DEBUG_BEGIN(x) Serial.begin(x)
  #define DEBUG_PRINT(x) Serial.print(x)
  #define DEBUG_PRINTLN(x) Serial.println(x)
  #define DEBUG_PRINT(x,y) Serial.print(x,y)
  #define DEBUG_PRINTLN(x,y) Serial.println(x,y)
#endif

DEBUG_PRINT("Will only print if MY_DEBUG is defined");
#define MY_DEBUG //comment to not run debug

#ifndef MY_DEBUG
  #define DEBUG_BEGIN(x)
  #define DEBUG_PRINT(x)
  #define DEBUG_PRINTLN(x)
  #define DEBUG_PRINT(x,y)
  #define DEBUG_PRINTLN(x,y)
#else
  #define DEBUG_BEGIN(x) Serial.begin(x)
  #define DEBUG_PRINT(x) Serial.print(x)
  #define DEBUG_PRINTLN(x) Serial.println(x)
  #define DEBUG_PRINT(x,y) Serial.print(x,y)
  #define DEBUG_PRINTLN(x,y) Serial.println(x,y)
#endif

DEBUG_PRINT(F("Will only print if MY_DEBUG is defined"));

{Discrete cough} Don't go introducing nasty bugs that are hard to find.

:slight_smile:

ok, what about this one?

#define DEBUG  // comment this line to disable serial prints

#ifndef DEBUG
  #define DEBUG_BEGIN
#else
  #define DEBUG_BEGIN Serial.begin(115200)
#endif

void setup() {
  DEBUG_BEGIN;
}

void loop() {
#ifdef DEBUG
  Serial.println("debug on");
#endif
}

this way you do not have to write everything twice...

Serial.println(F("debug on"));You missed this in my earlier post, it seems

no, i do not missed. just didn't know what the F() does... but right now i've read the docs: http://playground.arduino.cc/Learning/Memory

now i see, you recommend using the F() function, to prevent to fill up the ram with a lots of strings while debugging, right?