2

Suppose we have the following files (taken from The C++ Programming language by B.Stroustup):

stack.h

namespace Stack{
    void push(int);
    int pop();
    class Overflow{};
}

stack.cpp

#include "stack.h"

namespace Stack{
  const int max_size = 1000;
  int v[max_size];
  int top;
  class Overflow{};
}

void Stack::push(int elem){
  if(top >= max_size){
    throw Overflow();
  }
  v[top++] = elem;
}

int Stack::pop(){
  if(top <= 0){
    throw Overflow();
  }
  return v[--top];
}

I don't understand why declaration / definition (?) of class Overflow{} in stack.h has to be also written in stack.cpp?

Is it at all correct to write such code?

UPDATE

main.cpp

#include <iostream>
#include "stack.h"

using namespace std;

int main(){
  try{
    int a = 0;
    while(true){
      Stack::push(a++);
    }
  } catch(Stack::Overflow){
    cout << "Stack::Overflow exception, YEAH!" << endl;
  }

  return 0;
}

I compile the code with: g++ main.cpp stack.cpp -o main

g++ i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)

UPDATE (Solution)

Having tried g++ (Ubuntu/Linaro 4.7.3-1ubuntu1) 4.7.3 the code gave me an error: stack.cpp:7:9: error: redefinition of ‘class Stack::Overflow’. Which is of course correct.

Summary: the previously stated version of g++ on mac has a bug.

Timofey
  • 2,478
  • 3
  • 37
  • 53

1 Answers1

1

Because without it, there would be no definition of Overflow in stack.cpp and you couldn't use the class, such as in throw Overflow();.

It's common practice to expose the interfaces to the client through a header file and then include that same header in the implementation file. If we were to do that in this (rather unusual) case, we'd also need to expose the implementation details (max_size, v[], and top). The repeated class definition is there to avoid this, so the implementation details can be hidden from client code. It's not an error to have multiple class defintions, provided that they're indentical token by token and not present in the same translation unit.

EDIT: The question has been edited - now there's #include "stack.h" in stack.cpp that wasn't there previously.

That makes the program ill-formed - there are two definitons of class Overflow in the same translation unit (remember that include directive basically just copy-pastes the contents of a header file). It's in essence the same as if you did this:

int i;
int i; // error: redefinition of i
int main() {}

The fact that you can have several definitions of a class across the entire program is actually an exception to the One Definition Rule.

Community
  • 1
  • 1
jrok
  • 54,456
  • 9
  • 109
  • 141
  • I find it a bit misleading to define class in the interface rather than declare it. – Timofey Sep 21 '13 at 08:41
  • @Tim wait a second, did you edit the question and put `include "stack.h"` in the source file? – jrok Sep 21 '13 at 08:42
  • Yes I put #include "stack.h" into stack.cpp – Timofey Sep 21 '13 at 08:43
  • 1
    It wasn't initialy there, wasn't it? Because now the code is ill-formed, there can't be two definitions in the same translation unit. – jrok Sep 21 '13 at 08:44
  • well g++ i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00) compiles the only version of the code. If I remove class Overflow{} from stack.cpp it gives me: stack.cpp:13: error: ‘Overflow’ was not declared in this scope – Timofey Sep 21 '13 at 08:46
  • 1
    You must be compiling different code than the one in the question. – jrok Sep 21 '13 at 08:47
  • there is another file main.cpp which I added to the question. Does it change anything? – Timofey Sep 21 '13 at 08:49
  • Makes no difference, it's illformed code, because of `#include "stack.h"` inside stack.cpp. If that's verbatim from the book, it's an error. – jrok Sep 21 '13 at 08:54
  • why it is compiled than :D Can you compile it at your machine? (Hope it does not sound rude) – Timofey Sep 21 '13 at 08:56
  • My compiler gives a redefinition error as I expect it to. Yours could have a bug, it's been 6 years from its release afterall. – jrok Sep 21 '13 at 08:58