Не компилируется если //#ifdef

Тема в разделе "Микроконтроллеры AVR", создана пользователем Tomasina, 27 мар 2015.

  1. Tomasina

    Tomasina Сушитель лампочек Модератор

    Так все компилируется:
    Код (Text):
    #define DISPLAY

    #ifdef DISPLAY
       #include <Wire.h>
       #include <LiquidCrystal_I2C.h>
       LiquidCrystal_I2C lcd(0x20,16,2);
    #else
       Serial.begin(9600);
    #endif

    void setup(){
    pinMode(13, OUTPUT);
    }

    void loop(){
    }
    Так не компилируется (отличие только в первой строке):
    Код (Text):
    //#define DISPLAY

    #ifdef DISPLAY
       #include <Wire.h>
       #include <LiquidCrystal_I2C.h>
       LiquidCrystal_I2C lcd(0x20,16,2);
    #else
       Serial.begin(9600);
    #endif

    void setup(){
    pinMode(13, OUTPUT);
    }

    void loop(){
    }
    Почему?
     
  2. NR55RU

    NR55RU Гик

    Если я верно понял то тут проблема вот в чем.
    Во втором случае код для компилятора после препроцессора получается идентичным этому:
    Код (Text):
    Serial.begin(9600);

    void setup(){
    pinMode(13, OUTPUT);
    }

    void loop(){
    }
    На данном этапе объект Serial еще не существует, отсюда и беда. Я не знаю точно в какой момент именно создается объект Serial, но по всей видимости где то в промежутке межу данными объявленными пользователем в глобальной области видимости и вызовом функции setup.

    Решить эту проблему можно как вариант так:
    Код (Text):
    #define DISPLAY

    #ifdef DISPLAY
      #include <Wire.h>
      #include <LiquidCrystal_I2C.h>
      LiquidCrystal_I2C lcd(0x20,16,2);
    #endif

    void setup(){
    #ifndef DISPLAY
      Serial.begin(9600);
    #endif
    pinMode(13, OUTPUT);
    }

    void loop(){
    }
     
    Megakoteyka и Tomasina нравится это.
  3. Arduinщик

    Arduinщик Нерд


    Потому что знак // этот означает, что после этого знака идёт комментарий, а комментарий проверять не надо.
     
  4. Tomasina

    Tomasina Сушитель лампочек Модератор

    Суть не в Serial... Так тоже не работает:
    Код (Text):
    //#define DISPLAY

    #ifdef DISPLAY
      #include <Wire.h>
      #include <LiquidCrystal_I2C.h>
      LiquidCrystal_I2C lcd(0x20,16,2);
    #else
      #include <Wire.h>
    #endif

    void setup(){
      pinMode(13, OUTPUT);
    }

    void loop(){
    }
     
  5. geher

    geher Гуру

    Это может быть связано с багом Arduino IDE, который возникает в моиент преобразования скетча в програииу на си для скармливания компилятору.
    Если это оно, то перед первой директивой условной компиляции надо вставить хитрую комбинацию.
    Где-то на форуме уже упоминалось.
     
  6. Tomasina

    Tomasina Сушитель лампочек Модератор

    если вы про эту магию:
    Код (Text):
    // BOF preprocessor bug prevent - insert me on top of your arduino-code
    #if 1
    __asm volatile ("nop");
    #endif
    то не срабатывает, хотя некоторые уже сталкивались с аналогичной проблемой.

    Даже если максимально упростить, все равно ругается:
    Код (Text):
    //#define DISPLAY

    #ifdef DISPLAY
      #include <Wire.h>
      #include <LiquidCrystal_I2C.h>
      LiquidCrystal_I2C lcd(0x20,16,2);
    #endif

    void setup(){
      pinMode(13, OUTPUT);
    }

    void loop(){
    }
    v2_0.ino: In function 'void setup()':
    v2_0:14: error: 'OUTPUT' was not declared in this scope
    v2_0:14: error: 'pinMode' was not declared in this scope
     
  7. geher

    geher Гуру

    Поробовал на Arduino IDE 1.0.6 и 1.6.1.
    Только
    #include <LiquidCrystal_I2C.h>
    LiquidCrystal_I2C lcd(0x20,16,2);
    Заменил на аналогичное для простого LiquidCrystal.

    Без "магии" выдает именно такие ошибки, с ней ошибка пропадает.
    "Магию" применять сразу после //#define DISPLAY
     
  8. Tomasina

    Tomasina Сушитель лампочек Модератор

    у меня 1.0.5. Попробую 1.0.6 скачать.
     
  9. Unixon

    Unixon Оракул Модератор

    Добавьте первой строчкой в скетч
    #include <Arduino.h>
    и не используйте макрос DISPLAY (выберите другое имя, это уже используется внутри Wiring)
     
    amironov73 и Tomasina нравится это.
  10. Unixon

    Unixon Оракул Модератор

    В данном случае ошибки в IDE нет, просто при склеивании скетча с main.cpp получается неверная структура кода, #include и код, использующий библиотеки, получаются перемешаны.
     
    Tomasina нравится это.