Pages: [1] 2   Go Down
Author Topic: Compiler bug?  (Read 1238 times)
0 Members and 1 Guest are viewing this topic.
Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i porting my sketch from UNO to Atmega8 breadboard.
But I found one problem.
When I compilling sketch I get error about SoftwareSerial. (Is some problem with softwareserial function on Atmega8... But it is not needed in my sketch, I using sserial only for debugging).

So, software serial is forbidden via Debug function in my sketch. But why arduino compiler building software serial function, when I have commented it via debug function? Please, can you help me?

Code:

#include <avr/wdt.h>


//------------------------------------------------
//#define DEBUG    // Debug ON (this switch on software serial)                    DEBUG 1/2 !!!!
//------------------------------------------------
#ifdef DEBUG
#include <SoftwareSerial.h>
#endif

//SoftwareSerial mySerial(11, 12); // RX, TX
// if DEBUG, MUST be uncomment                                                  DEBUG 2/2 !!!!
// -------------------------------- debug
#ifdef DEBUG
#define DBG(x) x
#define DBG_PRINT(x) mySerial.println(x)
#define DBG_PRINTnoln(x) mySerial.print(x)
#else
#define DBG(x)
#define DBG_PRINT(x)
#define DBG_PRINTnoln(x)
#endif


void setup() {               
  wdt_enable(WDTO_2S); // have the wdt reset the chip
   
  // initialize the digital pin as an output.
  pinMode(led, OUTPUT);     
  pinMode(button, INPUT_PULLUP);
// initialize serial:
  Serial.begin(19200);

  #ifdef DEBUG
  mySerial.begin(19200);
  #endif

   DBG_PRINT("DBG: FUNCTION > =SETUP= is ending...");
 
}




In code I use this lines :

   DBG_PRINT("DBG> my debug note...");


Why compiler build sotfwareserial function, when I commented DEBUG variable? Is some error in my debug function or this is arduino bug? I don´t use any softwareserial function in SETUP or LOOP. When I change line :

#include <SoftwareSerial.h>

to

#include <SoxxxareSerial.h>

Now everything is OK and builded code is shorted. So arduino use some cache of libraries or this is some bug?

Many thanks,
Petr
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The IDE copies file to another directory for compilation. It ignores preprocessor directives when doing that. So, SoftwareSerial.h (and SoftwareSerial.cpp) get copied, and added to the list of files to be compiled.

When the compiler compiles your sketch, it sees that SoftwareSerial is not actually needed, and the linker doesn't care whether SoftwareSerial compiled, or not, since it isn't planning to link anything from SoftwareSerial.o into the hex file.

So, no, it is not a compiler bug. It is an IDE feature.
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 67
Posts: 2710
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The IDE copies file to another directory for compilation. It ignores preprocessor directives when doing that. So, SoftwareSerial.h (and SoftwareSerial.cpp) get copied, and added to the list of files to be compiled.

When the compiler compiles your sketch, it sees that SoftwareSerial is not actually needed, and the linker doesn't care whether SoftwareSerial compiled, or not, since it isn't planning to link anything from SoftwareSerial.o into the hex file.

So, no, it is not a compiler bug. It is an IDE feature.

If it were only that simple and actually worked that way.

In reality what happens is that the IDE tries to be "smart" and make things easier for the user by
not requiring the user to write valid/correct/proper C/C++ code.
In order to do this, it has to correct the users code for things like missing function prototypes
and forward variable references.
(That is why it must make a copy of your code into a temporary working area)
In order to do that, it goes in and tries to analyze your code to be able to create prototypes for the functions
and pull in the libraries "it thinks" the code uses and declare references for certain known objects.

And there is where the problem is.
The IDE is simply not smart enough to pull that off.
(BTW, that is a very difficult thing to do properly)
The code that does the analyzing is too simple and doesn't understand even some simple things
like conditional compilation.
As a result it will try to pull in code that is no used
and then depend on the linker to remove it later.

In this case, with the SoftSerial code, the linker cannot remove the code and
the code will be pulled in even though the user code is not referencing or using any of it.
This is because the SoftSerial code uses interrupts and has an ISR routine.
The way the code is written, declared ISR routines will always be pulled in, and because of that other SoftSerial routines
are pulled in, and then because of those, most if not all the  SoftSerial code and data variables
will be pulled in.

You can see this if you use avr-objdump to create a .lss file and then look at what code is actually
included into the final linked .elf file that will be used to create the final .hex image  which
is what will be uploaded to the AVR.

This is a great example of how the current Arduino build methodology simply doesn't work very well.
There are some simple things that could be done to avoid things like this but so far the Arduino Team
seems very unwilling to address things like this.

If you look at the .lss file you will also see the HardwarSerial code and data being pulled.
Similar thing going on there as well. It is part of the core code and since it has ISRs it
ends up getting pulled in.

This is all done because of combination of the build methodology and the way the code is written/declared/used.
There are some ways to fix this but it takes modifications to the actual library code and to the IDE
so it's not really something than an average Arduino user will be able to fix.

So from my point of view, I see this as a well intended "feature" that kind of sort of works,
but in reality creates many other subtle hard to work around issues.

--- bill


« Last Edit: February 16, 2013, 10:53:15 am by bperrybap » Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Ok, many thanks for explanation.
I can accept this reality if I used "IF" function :

Code:
#ifdef DEBUG
#include <SoftwareSerial.h>
#endif

But why compiller can not ignore this line when I commented this?

when I make :

Code:
//#ifdef DEBUG
//#include <SoftwareSerial.h>
//#endif

I thought comments are absolutely ignored. So why arduino IDE use this if methods and softwareserial include line when it is commented?

I will be confused when I must remove or update everything debug declarations and functions before compile code.
Logged

Seattle, WA USA
Offline Offline
Brattain Member
*****
Karma: 617
Posts: 49463
Seattle, WA USA
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
But why compiller can not ignore this line when I commented this?
It does. It would really help if you explained the errors you are getting, instead of us guessing.
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

C:\arduino-1.0.2\hardware\tools\avr\bin\avr-g++ -c -g -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -mmcu=atmega8 -DF_CPU=16000000L -MMD -DUSB_VID=null -DUSB_PID=null -DARDUINO=102 -IC:\arduino-1.0.2\hardware\arduino\cores\arduino -IC:\arduino-1.0.2\hardware\arduino\variants\standard -IC:\arduino-1.0.2\libraries\SoftwareSerial -IC:\arduino-1.0.2\libraries\SoftwareSerial\utility C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp -o C:\DOCUME~1\Notebook\LOCALS~1\Temp\build1882666110994170942.tmp\SoftwareSerial\SoftwareSerial.cpp.o
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp:59: warning: only initialized variables can be placed into program memory area
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp: In member function 'void SoftwareSerial::begin(long int)':
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp:396: error: 'PCICR' was not declared in this scope
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp:399: error: 'PCMSK2' was not declared in this scope
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp:399: error: 'PCMSK0' was not declared in this scope
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp:399: error: 'PCMSK1' was not declared in this scope
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp: In member function 'void SoftwareSerial::end()':
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp:414: error: 'PCMSK2' was not declared in this scope
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp:414: error: 'PCMSK0' was not declared in this scope
C:\arduino-1.0.2\libraries\SoftwareSerial\SoftwareSerial.cpp:414: error: 'PCMSK1' was not declared in this scope
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 67
Posts: 2710
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

The compiler and the IDE are not the same thing.

The compiler works correctly and the way you expect things to work.
It is the IDE that is not working the way you expect.

The IDE has the problem not the compiler.

In your example code above you commented out the #define
The ifdef and include are not commented out.
The IDE is DUMB. It does not understand ifdefs it simply looks
for #includes and if it sees them for a library,
 (even if inside code that is conditionally not used by the compiler),
the IDE will build the library and link against.

This is what I talked about earlier.

--- bill
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This error when I use :

Code:
/*
//------------------------------------------------
//#define DEBUG    // zapnout LADENI (zapne software serial)                    DEBUG 1/2 !!!!
//------------------------------------------------
#ifdef DEBUG
#include <SoftwareSerial.h>
#endif
*/



when I make :

Code:
/*
//------------------------------------------------
//#define DEBUG    // zapnout LADENI (zapne software serial)                    DEBUG 1/2 !!!!
//------------------------------------------------
#ifdef DEBUG
#include <SXXXwareSerial.h>
#endif
*/


now everything is ok and compiled done...

Do why compiller accept commented lines? It´s bug! :-)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I understand everything if I use only IFDEF procedure...

But when I comment whole block as I post at top, I don´t know why IDE can not ignore it and still using this commented lines...

Only when I corrupt name of include - Sxxxrial - now IDE ignore it... It´s very bad :-(
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 67
Posts: 2710
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Some of the errors you are geting looks
like you are running into another "feature" (bug) of the IDE.
The IDE for some crazy reason trys to look for code inside your code
in order to place the include for its include.

In order work around this I recommend creating a line of code at the very top of your code
to force the IDE to place it's include at the top vs down lower which probably lands inside
your ifdef.

So place this line at the very top of your code:

Code:
static char stupidIDE;

This will trick/force the IDE into placing its header file correctly into your working
temporary file and since your code is not referencing the dummy variable, the linker will remove it.

---- bill
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This no help :-(




Code:
static char stupidIDE;

This will trick/force the IDE into placing its header file correctly into your working
temporary file and since your code is not referencing the dummy variable, the linker will remove it.

---- bill
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 67
Posts: 2710
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I understand everything if I use only IFDEF procedure...

But when I comment whole block as I post at top, I don´t know why IDE can not ignore it and still using this commented lines...

Only when I corrupt name of include - Sxxxrial - now IDE ignore it... It´s very bad :-(

But you didn't comment out everything in the code example in your first post.
This was in that code:
Code:
//------------------------------------------------
//#define DEBUG    // Debug ON (this switch on software serial)                    DEBUG 1/2 !!!!
//------------------------------------------------
#ifdef DEBUG
#include <SoftwareSerial.h>
#endif

The #include is not commented out.
It is inside a conditional compilation block controlled by the define DEBUG but that is not a comment.
While the compiler understands conditionals, the IDE does not.

The IDE saw the include for the SoftwareSerial header and
assumes a reference to SoftwareSerial and so it decided to help you out by
including the library for you as part of the build.
(The IDE tells the compiler what to compile and the linker what to link)

The errors I saw from your compilation were not related to this.
They appeared to be related to the IDE incorrectly inserting its "Arduino.h" header and prototypes
incorrectly.

Attached are examples of how the IDE creates your .cpp file with/without the dummy variable declaration
at the top of you code.
When including header files and especially when doing any conditional compilation, it is usually mandatory
to add this dummy variable to the top of your sketch code because the IDE can often drop its header include
and declarations in a bad location rather than at the top where it needs to be.

To avoid the IDE issue of incorrectly inserting its header and prototypes, I always declare
a dummy static variable at the very top of all my code that is used with the Arduino IDE.

--- bill

* test3a.cpp (1.06 KB - downloaded 18 times.)
* test3b.cpp (1.08 KB - downloaded 15 times.)
Logged

Dallas, TX USA
Offline Offline
Faraday Member
**
Karma: 67
Posts: 2710
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

This no help :-(
Your example code from your initial post (cleaned up a little) compiled just fine for me.
(I had to correct a few things).
It is a attached.

--- bill

* test3.pde (1.04 KB - downloaded 14 times.)
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Do you compile it for ATMEGA8 ? when I compile it for UNO, everything is ok - atmega8 cannot accept software serial so for this reason make error. This is why I found this error. When I use UNO, I can not see when software serial is compiled. it is silent.

My first code i WRONG !!! I compile it with my second code in middle of this topic.
When I use IFDEF, I can hope IDE use include directive.

But I use this :
Code:
/*
//------------------------------------------------
//#define DEBUG    // zapnout LADENI (zapne software serial)                    DEBUG 1/2 !!!!
//------------------------------------------------
//#ifdef DEBUG
//#include <SoftwareSerial.h>
//#endif
*/
//SoftwareSerial mySerial(11, 12); // RX, TX
// if DEBUG, MUST be uncomment   

and still I GET error about software serial, which IS COMMENTED .....

You must select arduino board : Arduino NG or older w/ Atmega8.... UNO work super with softwareserial and you can not find this error...
Logged

Offline Offline
Newbie
*
Karma: 0
Posts: 29
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

But it is not error in header files, libraries etc... it is Arduino IDE error.. When i change commented line with
Include softwareserial to Include xxxserial - now everything is ok.... Now arduino dont send error about software serial and dont compile software serial.

Logged

Pages: [1] 2   Go Up
Jump to: