0

Given the following code:

// foo.h
#ifdef BIG_DATA_MACRO
    #warning "TEXT ADDED"
    #define TEXT_HANDLING_MACRO  \
         static const char * TEXT[]; \
         static const char * getText( int _enum ) { \
             return TEXT[_enum]; \
         }
#else
    #warning "TEXT NOT ADDED"
    #define TEXT_HANDLING_MACRO
#endif

struct Foo {
    TEXT_HANDLING_MACRO
};

// foo.cpp
#include "foo.h"
#ifdef BIG_DATA_MACRO
    const char * Foo::TEXT[] = { 
        "ONE",
        "TWO",
        "THREE",
        0
   };
 #endif

// other_file.cpp
#include <iostream>
#define BIG_DATA_MACRO  
#include "foo.h"
void bar() {
    std::cout << Foo::TEXT[0] <<std::endl;
}

The warning TEXT ADDED appears everywhere, but TEXT NOT ADDED appears for moc_other_file.cpp. How can we fix this bug. The compilation output is:

/foo.h:15: warning: #warning "TEXT NOT ADDED" [-Wcpp] Debug/moc_other_file.cpp:9: from moc_otherfile.cpp:9:

other_file.cpp:26: error: undefined reference to 'Foo::TEXT'

Community
  • 1
  • 1
Oli
  • 1,313
  • 14
  • 31
  • `moc` processes the `.cpp` file *as is* -- it does *not* run the `C` preprocessor first. If the result of preprocessing affects the `moc` output then you'll need to arrange for your build environment to preprocess the `.cpp` file and then run `moc` on the result. – G.M. Oct 24 '16 at 11:56
  • @G.M.: I think you mean it processes the `.h` (or `.hpp`) file. – MSalters Oct 24 '16 at 11:59
  • How can I do that, I have default project file in Qt which do all the things. – Oli Oct 24 '16 at 12:00
  • @MSalters -- Well, it processes whatever you give it *as is*. In general that can include `.cpp` and/or `.hpp` files. – G.M. Oct 24 '16 at 12:05
  • @G.M. Uhh, moc **definitely** preprocesses the files! In both Qt 5 and Qt 4. – Kuba hasn't forgotten Monica Oct 24 '16 at 13:20
  • @KubaOber -- My bad. I forgot about the `-I` and macro args that can be passed to it (I don't use `moc` much these days). Sorry for the noise. With that in mind, however, those `moc` flags are probably what's missing from the OPs generated makefiles. – G.M. Oct 24 '16 at 13:28
  • @G.M. You must pass the **same** include paths and defines to `moc` as you do to the C++ compiler, otherwise you'll get wrong results. – Kuba hasn't forgotten Monica Oct 24 '16 at 14:35

1 Answers1

1

moc_other_file.cpp, as the name says, is NOT other_file.cpp. Hence, the fact that you defined BIG_DATA_MACRO in other_file.cpp has no impact on moc_other_file.cpp.

That said, you still miss a definition of TEXT. You simply need to add that.

As a matter of opinion, TEXT is a fairly bad name; uppercase identifiers are usually used for macro's. TEXT in particular is a macro used in Windows.h.

MSalters
  • 173,980
  • 10
  • 155
  • 350
  • moc_other_file.cpp is generated automatically by Qt because of signals and slots. – Oli Oct 24 '16 at 11:49
  • so I can not #define macro in moc_other_file.cpp. – Oli Oct 24 '16 at 11:52
  • But why would a signal or slot need the definition of `TEXT` ?! – MSalters Oct 24 '16 at 12:00
  • foo.h contains a lot of constants, as enums. In need to define the name of these enum as TEXT for my GUI application. But I don't want to include "text" portion for microcontroller has limited memory. I want to use same file for bother microcontroller and GUI application, but controlled by `#define BIG_DATA_MACRO` – Oli Oct 24 '16 at 12:04
  • @has: A header file should contain declarations, not definitions. Even so, why would your _signals_ and _slots_ need `TEXT`? That's a bad idea even before you mentioned microcontrollers. – MSalters Oct 24 '16 at 12:35
  • My class in QUI needs QObject. My class contains different widgets that requires the "TEXT". Header file only contains declarations, I have also included another file by modifying my question. – Oli Oct 24 '16 at 12:41
  • The `struct Foo` definition in `foo.h` is almost certainly wrong. It must be defined the same way throughout the project; you can't have it's contents depend on `BIG_DATA_MACRO`. The best solution would be to simply not define `Foo` at all when `BIG_DATA_MACRO` is missing. – MSalters Oct 24 '16 at 14:14
  • `struct Foo` is partially shown in the code example above. It also contains lots of enums. If I put `#define BIG_DATA_MACRO` on top of foo.h, the code compile and executes as expected. Instead if I put '#define BIG_DATA_MACRO` on top of `other_file.cpp`, then during compile time, every one expand `BIG_DATA_MACRO` except `moc_other_file.cpp`. – Oli Oct 24 '16 at 14:19