0

I saw this question and I tried to do as the answer to that question said. To use the extern keyword in the header file to define an array and then declare it outside of that namespace or class in a other cpp file.

It didn't work for me really, I'm not sure if it because I'm using a void pointer array (i.e void* array[]) or if it's just my ignorance that prevents me from seeing the problem.

This is the shortest example I can come up with:
[cpp.cpp]

#include "h.h"

void main(){
    void* a::b[] = {
        a::c = a::d(1)
    };
}

[h.h]

namespace a{
    struct T* c;
    struct T* d(int e);
    extern void* b[];
}

So the problem is that I receive the error: IntelliSense: variable "a::b" cannot be defined in the current scope

And I have no clue why that is.

Community
  • 1
  • 1
Linus
  • 1,516
  • 17
  • 35
  • 3
    How is it briefer if you have to also post that disclaimer? – Oliver Charlesworth Aug 16 '14 at 18:15
  • 2
    `int` is one character shorter than `void`... `a::b` is declared outside of a function, the definition should be outside as well, why are you writing it inside `main`? – Marc Glisse Aug 16 '14 at 18:20
  • So instead of fixing `void main()` you deleted the reasoning for why you typed something incorrect to begin with. Brilliant. And the definition of `a::b` needs to be at namespace scope, not block scope. – Praetorian Aug 16 '14 at 18:21
  • @MarcGlisse Because I wanted the shortest version possible, I used `void main`, because then I don't have to return anything. – Linus Aug 16 '14 at 18:22
  • @Linus It's perfectly legal to omit the return statement in `int main() { ... }` – Praetorian Aug 16 '14 at 18:23
  • `return 0;` is implicit for `main` in C++. Ok, that's an obscure detail... – Marc Glisse Aug 16 '14 at 18:23
  • @Praetorian Okay, I didn't know that. But that's due to my ignorance in the C++ language. What do you mean that it needs to be at namespace scope? – Linus Aug 16 '14 at 18:26
  • @MarcGlisse I'm defining it in the main function because I will access it from other places as well, and it doesn't make any sense to me to define something in a header file, I know it is legal but I think of everything in a header file as declarations. – Linus Aug 16 '14 at 18:28
  • @Linus There are places in the .cpp file that are not inside the function `main`... – Marc Glisse Aug 16 '14 at 18:30
  • @Linus [Here's an example](http://coliru.stacked-crooked.com/a/556e19461c33071e) – Praetorian Aug 16 '14 at 18:30
  • @Praetorian That was simple, it was my ignorance then... Would you mind explaining why it can't be defined in a method? – Linus Aug 16 '14 at 18:32
  • @Linus You declared a namespace scope variable. So it wouldn't make sense for the definition to be visible only within a particular block (in this case `main`) – Praetorian Aug 16 '14 at 18:49

1 Answers1

2

First, you should declare main() as int ! See here why.

Declaring your array as extern in a namespace means that it belongs to the namespace but is defined somewhere ele, normally in a separate compilation unit.

Unfortunately, in your main(), you try to redefine the element as a local variable. This explains the error message you receive.

You shoud do as follows:

#include "h.h"
void* a::b[] { a::c, a::d(1) };         // global variable belonging to namespace

int main()                  // int!!!
{
    /* your code here */  
}

The code will compile. The fact that a::b[] is defined in the same compiling unit is accepted. But the linker will complain because a::d(1) is a call to the function d returning a pointer to a struct, and this function is defined nowhere.

Therfore you should also define this:

namespace a { 
    struct T* d(int e)
    {
        return nullptr;         // in reality you should return a pointer to struct T
    }
} 

Interestingly, struct T does not need to work for this code to compile and link.

Christophe
  • 68,716
  • 7
  • 72
  • 138