-1

I have a problem regarding following code (these are only snippets, not full files):

Menu.h

#ifndef MENU_H
#define MENU_H

#include <Adafruit_SSD1306.h>
#include <stdint.h>

#include <Config.h>

class MenuHeader; // forward declaration of class MenuHeader
class MenuPage; // forward declaration of class MenuPage

class Menu {
    MenuHeader* m_header{nullptr};
    MenuPage* m_pages[16]{}; // support up to 16 pages
    uint8_t m_pagesCount{0};
    uint8_t m_currentPage{0};

    public:
    void setHeader(MenuHeader* header);
    void addPage(MenuPage* page);
    void goToPage(const char* pageName);
    void next();
    void prev();
    void click();
    void draw(Adafruit_SSD1306* display);
};

#endif

Menu.cpp

#include <Menu.h>
#include <MenuHeader.h>
#include <MenuPage.h>

/* Some other definitions */

void Menu::draw(Adafruit_SSD1306* display) {
    if(m_header != nullptr) {
        display->setCursor(0, HEADER_HEIGHT - 1 + SCREEN_Y_OFFSET);
        m_pages[m_currentPage]->draw(display);
        m_header->draw(display);
    } else {
        display->setCursor(0, SCREEN_Y_OFFSET);
        m_pages[m_currentPage]->draw(display);
    }
}

Config.h

#ifndef CONFIG_H
#define CONFIG_H

#include <stdint.h>

constexpr uint8_t ENCODER_PIN_A = 14; // pin A of rotary encoder
constexpr uint8_t ENCODER_PIN_B = 12; // pin B of rotary encoder
constexpr uint8_t BUTTON_PIN = 13; // pin to which button is connected

constexpr uint8_t SCREEN_WIDTH = 128; // width of screen in pixels
constexpr uint8_t SCREEN_HEIGHT = 64; // height of screen in pixels
constexpr uint8_t CHARS_PER_LINE = 18; // how many characters fit in one line
constexpr uint8_t CHAR_WIDTH = SCREEN_WIDTH/CHARS_PER_LINE; // width of single character
constexpr uint8_t CHAR_HEIGHT = 10; // height of single char
constexpr uint8_t SCREEN_Y_OFFSET = CHAR_HEIGHT; // screen offset, if not using custom font set to 0

constexpr uint8_t HEADER_HEIGHT = 14; // menu header height in pixels

constexpr int8_t TIMEZONE = -1; // timezone

/* Some other not needed stuff */

#endif

All headers (Menu.h, MenuHeader.h, MenuPage.h) include Config.h.

Well, compiler seems not to like it. It throws:

'HEADER_HEIGHT' was not declared in this scope
identifier "HEADER_HEIGHT" is undefined
'SCREEN_Y_OFFSET' was not declared in this scope
identifier "SCREEN_Y_OFFSET" is undefined

All regarding Menu.cpp file. I thought that if I include Config.h file in one of headers which I then include in my Main.cpp, it should work. Even if I include config directly in Main.cpp - the same errors occur. What can I do about that?

EDIT: Well, weird things are happenning. If I have #include <Config.h> in Menu.h, config only works in that file. If I change it to #include "../Config/Config.h", it works in both Menu.h and Menu.cpp. What's going on? My folder structure Using <Config.h> is platformio's feature. It automatically finds all libraries and compiles them.

  • Why `constexpr` instead of `const` for what are just simple constant values? – tadman Oct 01 '18 at 16:43
  • Tried both. Both not working. I Just thought that constexpr might be better in my case. –  Oct 01 '18 at 16:44
  • It's also odd to see user-defined headers included with `<...>` style instead of the more conventional `#include "myheader.h"`. – tadman Oct 01 '18 at 16:44
  • `constexpr`, as the name indicates, is for constant *expressions*, not just simple constants. You normally use `constexpr` for function definitions. – tadman Oct 01 '18 at 16:45
  • 2
    my guess - some other header already defined CONIFG_H, try __CONFIG___H__ – pm100 Oct 01 '18 at 16:45
  • 2
    As @pm100 points out, you may have namespace collisions here. As it's 2018 you might also want to check if your compiler supports [`#pragma once`](https://en.wikipedia.org/wiki/Pragma_once) to avoid all this `#ifndef` nonsense. – tadman Oct 01 '18 at 16:46
  • Well it doesnt change anything anyway. I Can use <> because i use platformio extension for vs code –  Oct 01 '18 at 16:47
  • 1
    That extension sounds either misconfigured or super broken if it doesn't understand the `"..."` style that's been around since the 1970s. – tadman Oct 01 '18 at 16:48
  • I don’t think it’s a problem with ifndef. There are no other headers named like that and that problem sometimes occurs sometimes not. For example it works correctly in header files mentioned earlier but not in this one –  Oct 01 '18 at 17:11
  • I can post a link to my github repo if that helps –  Oct 01 '18 at 17:12
  • Regarding constexpr - I based my knowledge on this one: https://stackoverflow.com/a/13347355/10265033 –  Oct 01 '18 at 17:14
  • ***I can post a link to my github repo if that helps*** Remember the main purpose of a question is to help future readers with the same problem. This is why we require the minimal code to be here not on an external site. – drescherjm Oct 01 '18 at 17:18
  • Sure, I got it. –  Oct 01 '18 at 17:19
  • did you try changing the CONFIG_H to a different name, takes 2 seconds to try it – pm100 Oct 01 '18 at 17:20
  • @pm100 double underscore in an identifier is reserved. Don't use it. Otherwise your advise is sound. – Martin York Oct 01 '18 at 17:38
  • Steps I've taken: Changed define name to CONFIG_HH, Changed ifndef to pragma once, Changed constexpr to const. None of them worked –  Oct 01 '18 at 19:14
  • I've updated post. Found a problem but still don't know why it doesn't work –  Oct 01 '18 at 19:47

2 Answers2

2

This does not look correct:

#include <Config.h>

You are including a Config.h from the system include path.
I presume you want to include a Config.h from the application include path.

#include "Config.h" // Note the quotes rather than the < >

Check where you include paths are looking:

https://stackoverflow.com/a/11946295/14065

See if there is another "Config.h" in one of the two sets of paths.

Also note:

This also looks wrong:

#include <stdint.h>

This is to include the C version of integer types. Which is unlikely to correctly place these definitions in std.

<cstdint> vs <stdint.h>

You should be using the correct header files for C++:

#include <cstdint>
Martin York
  • 257,169
  • 86
  • 333
  • 562
  • is correct, I use PlatformIO extension which compiles libs for me. Thanks for pointing out problem with cstdint –  Oct 01 '18 at 18:13
0

Found a problem. Turned out that Config is probably reserved name and that's why it didn't work. Changing name to CFG fixed the problem. Thanks for your time.

  • Was it another file called "Config.h" or was it the macro "CONFIG_H" that was already defined? – Martin York Oct 02 '18 at 00:14
  • None of them. I don’t have any files called Config.h and I changed all ifndefs to Pragma once. Only Changing name helped. –  Oct 02 '18 at 05:26
  • So there was another "Config.h" file in one of the include directories that was included instead of your header file. – Martin York Oct 02 '18 at 06:13
  • Just checked that now. You’re right. There is a Config.h file for esp8266 library. I haven’t noticed it because that lib isn’t in my working directory. Although I don’t know why it sometimes worked –  Oct 02 '18 at 06:24
  • 1
    See my answer. Use "" rather than <> to include local version of the file rather than the file in one of the system include directory. – Martin York Oct 02 '18 at 06:29
  • Yes I’ve seen it. It’s working even with <> now. Please check this link and you’ll see why do I use it. https://github.com/sszczep/PCB-Etching-Tank/blob/master/lib/readme.txt –  Oct 02 '18 at 06:32