include order

Y

yuri

Hello,
I wrote this simple stack:


---START---------------
#include "stackArr.h"
#include "underflow.h"
#include <iostream>

StackArr::StackArr(int initialSize){
data = new void*[initialSize];
size = 0;
};

StackArr::~StackArr(){
delete []data;
}

void StackArr::push(void* x){
data[size] = x;
size++;
}

void StackArr::pop(){
if(size==0) throw new Underflow("Stack empty");
size--;
}

void* StackArr::top() const{
if(size==0) throw new Underflow("Stack empty");
return data[size-1];
}

void* StackArr::topAndPop(){
if(size==0) throw new Underflow("Stack empty");
return data[size--];
}

bool StackArr::isEmpty() const{
return size==0;
}

void StackArr::makeEmpty(){
delete []data;
data = new void*[10];
size=0;
}

int main(){
cout<<"StackArr"<<endl;
}

---END-----------------

When I compile this version there isn't problem, but when I change the
include order (first iostream)

#include <iostream>
#include "stackArr.h"
#include "underflow.h"

I have compile errors:
stackArr.cpp: In member function `virtual void StackArr::pop()':
stackArr.cpp:23: parse error before `(' token
stackArr.cpp: In member function `virtual void* StackArr::top() const':
stackArr.cpp:28: parse error before `(' token
stackArr.cpp: In member function `virtual void* StackArr::topAndPop()':

Why???????
Thanks
Yuri
 
K

Kevin Goodsell

yuri said:
Hello,
I wrote this simple stack:

When I compile this version there isn't problem, but when I change the
include order (first iostream)

#include <iostream>
#include "stackArr.h"
#include "underflow.h"

I have compile errors:
stackArr.cpp: In member function `virtual void StackArr::pop()':
stackArr.cpp:23: parse error before `(' token
stackArr.cpp: In member function `virtual void* StackArr::top() const':
stackArr.cpp:28: parse error before `(' token
stackArr.cpp: In member function `virtual void* StackArr::topAndPop()':

Why???????

Probably because you've done something wrong in your header files. We
don't know what, since you didn't bother to include the code from those
files.

http://www.parashift.com/c++-faq-lite/how-to-post.html#faq-5.8

-Kevin
 
Y

yuri

Sorry, I have forgotten the header!!!

---underflow.h---
#ifndef UNDERFLOW
#define UNDERFLOW

class Underflow{
public:
Underflow(char* e="Underflow Exception"): err(e){};
private:
char* err;
};

#endif //UNDERFLOW


---stackArr.h---
#include "stack.h"

class StackArr: public Stack{
public:
StackArr(int initialSize=10);
~StackArr();
void push(void*);
void pop();
void* top() const;
void* topAndPop();
bool isEmpty() const;
void makeEmpty();
private:
void** data;
int size;
};

---stack.h--
#ifndef STACK
#define STACK

class Stack{
public:
//Stack(){};
virtual void push(void*) = 0;
virtual void pop() = 0;
virtual void* top() const = 0;
virtual void* topAndPop() = 0;
virtual bool isEmpty() const = 0;
virtual void makeEmpty() = 0;
};

#endif

But I think I find the error. In iostream.h there is the definition of
macro UNDERFLOW (I think...) so when iostream is include at the begining,
the macro UNDERFLOW is define and the definition of class Underflow is not
included because I use the same macro name. Is it ok?
Thanks
Yuri
 
K

Kevin Goodsell

yuri said:
Sorry, I have forgotten the header!!!

But I think I find the error. In iostream.h

There is no header called <iostream.h> in standard C++. Standard C++
uses said:
there is the definition of
macro UNDERFLOW (I think...)

This would be illegal. Standard headers are required to use identifiers
that don't conflict with identifiers the programmer may use. So, the
standard header could use _UNDERFLOW because identifiers beginning with
an underscore followed by an uppercase letter are reserved for that
purpose. But it may not use UNDERFLOW - that identifier is reserved for
the programmer's use.
so when iostream is include at the begining,
the macro UNDERFLOW is define and the definition of class Underflow is not
included because I use the same macro name. Is it ok?

If that's the problem, your implementation is broken. I haven't taken a
close look at the headers you posted yet. I'll let you know if I see a
problem there.

-Kevin
 
K

Kevin Goodsell

yuri said:
Sorry, I have forgotten the header!!!

---underflow.h---
#ifndef UNDERFLOW
#define UNDERFLOW

class Underflow{
public:
Underflow(char* e="Underflow Exception"): err(e){};

Implicit conversion from a string literal to a (non-const) char pointer
is dangerous and deprecated. Always use const char* for this purpose.
private:
char* err;
};

#endif //UNDERFLOW


---stackArr.h---
#include "stack.h"

class StackArr: public Stack{

No include guards for this file? That's asking for trouble.

Other than this, I was not able to find a problem in the code or
reproduce your error. Perhaps if you told us what compiler and library
you are using (including version numbers) and posted the exact code that
gave the error (the posted code is illegal as is - 'cout' and 'endl' are
undeclared) we could be of more help.

-Kevin
 
P

Pete Becker

Kevin said:
There is no header called <iostream.h> in standard C++. Standard C++


This would be illegal. Standard headers are required to use identifiers
that don't conflict with identifiers the programmer may use.

You can't have it both ways. If <iostream.h> isn't a standard header, it
shouldn't use names in the implementors' namespace.
 
K

Kevin Goodsell

Pete said:
You can't have it both ways. If <iostream.h> isn't a standard header, it
shouldn't use names in the implementors' namespace.

True, but the original code actually used <iostream>. So, if the poster
actually meant <iostream> rather than <iostream.h>, what I said is true
(unless I've made a mistake).

-Kevin
 
P

Pete Becker

Kevin said:
True, but the original code actually used <iostream>. So, if the poster
actually meant <iostream> rather than <iostream.h>, what I said is true
(unless I've made a mistake).

He said he found the problem, and he described it. It involved a macro
defined in <iostream.h>. There's nothing more to say.
 
R

Ron Natalie

Kevin Goodsell said:
If that's the problem, your implementation is broken. I haven't taken a
close look at the headers you posted yet. I'll let you know if I see a
problem there.

It looks like that may indeed be his problem. For whatever reason it looks like
Underflow is not defined at the point of the error. I suggest he use a more elaborate
include guard variable. Even if the standard headers don't use (legitimately) names
of that form, UNDERFLOW, is a symbol that's likely to collide with somebodies
header or program at somepoint. I tend to do things like
INCLUDE_UNDERFLOW_H
not fool proof, but less likely to be anything other than an include guard.

A cute hack to determine whether UNDERFLOW is infact being defined prematurely
is to insert a definition for it prior to any #includes:


#define UNDERFLOW 1.2.3.4 // almost sure to be a syntax error when used.
#include "stackArr.h"
#include "...

You will most likely get an error from the preprocessor the first time UNDERFLOW is defined
or used after it's definition above.

-Ron
 
Y

yuri

Thanks Kevin for your useful help and attention!
I have found the definition of UNDERFLOW macro! I wrote a simple program
using the Ron's idea and I found the macro UNDERFLOW's definition.
It's in /usr/include/math.h and the error output of compiler is (x.cpp is
my test program:

x.cpp:2:1: warning: "UNDERFLOW" redefined
In file included from /usr/include/c++/3.2.2/cmath:51,
from /usr/include/c++/3.2.2/bits/locale_facets.tcc:41,
from /usr/include/c++/3.2.2/locale:46,
from /usr/include/c++/3.2.2/bits/ostream.tcc:37,
from /usr/include/c++/3.2.2/ostream:275,
from /usr/include/c++/3.2.2/iostream:45,
from x.cpp:1:
/usr/include/math.h:299:1: warning: this is the location of the previous definition

Now I will use only complicated header :))
Bye
Yuri
 
Y

yuri

I have another problem!
My x.cpp file is:

#include <iostream>
#define UNDERFLOW 2

using namespace std;

int main(){
#ifdef UNDERFLOW
cout<<UNDERFLOW<<endl;
#endif
cout<<"end"<<endl;
}

Compiling I have warning (see my last post) that tell me UNDERFLOW is
define in math.h (/usr/include/math.h) and it's value is 4.
But if I swap the first two rows:

#define UNDERFLOW 2
#include <iostream>
....
I haven't compiling error or warning and cout prints the math.h value (4).
Why? Maybe the macros of math.h have precedence over mine?
Thanks
Yuri
 
K

Kevin Goodsell

yuri said:
I have another problem!
My x.cpp file is:

#include <iostream>
#define UNDERFLOW 2

using namespace std;

int main(){
#ifdef UNDERFLOW
cout<<UNDERFLOW<<endl;
#endif
cout<<"end"<<endl;
}

Compiling I have warning (see my last post) that tell me UNDERFLOW is
define in math.h (/usr/include/math.h) and it's value is 4.
But if I swap the first two rows:

#define UNDERFLOW 2
#include <iostream>
...
I haven't compiling error or warning and cout prints the math.h value (4).
Why? Maybe the macros of math.h have precedence over mine?

It could do

#undef UNDERFLOW
#define UNDERFLOW 4

easily enough.

But the main issue here is that UNDERFLOW is reserved for the
programmer's use - your standard library SHOULD NOT #define it. The
implementation is broken. You should check if a fix is available.

-Kevin
 
K

Kevin Goodsell

Kevin said:
But the main issue here is that UNDERFLOW is reserved for the
programmer's use - your standard library SHOULD NOT #define it. The
implementation is broken. You should check if a fix is available.

Actually, I bet the fix is to invoke your compiler correctly. Try
compiling with the following options:

-W -Wall -ansi -pedantic

If I am reading the docs right, -ansi applies for C++ mode also (which
is a little weird I think, since ISO, not ANSI, standardized C++ (OK, it
was a joint ANSI/ISO group, but ISO takes precedence, IMO)).

I looked at the math.h header, and it looks like UNDERFLOW is
conditionally added as part of some kind of System V compatibility
thing. My guess is that the options I listed will fix it.

-Kevin
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,527
Members
44,997
Latest member
mileyka

Latest Threads

Top