tags:

views:

318

answers:

2

I have this source code from 2001 that I would like to compile.

It gives this:

$ make
g++ -O99 -Wall -DLINUX -pedantic   -c -o audio.o audio.cpp
In file included from audio.cpp:7:
audio.h:14: error: use of enum ‘mad_flow’ without previous declaration
audio.h:15: error: use of enum ‘mad_flow’ without previous declaration
audio.h:17: error: use of enum ‘mad_flow’ without previous declaration
audio.cpp: In function ‘mad_flow audio::input(void*, mad_stream*)’:
audio.cpp:19: error: new declaration ‘mad_flow audio::input(void*, mad_stream*)’
audio.h:14: error: ambiguates old declaration ‘int audio::input(void*, mad_stream*)’
audio.h:11: error: ‘size_t audio::stream::BufferPos’ is private
audio.cpp:23: error: within this context
audio.h:11: error: ‘size_t audio::stream::BufferSize’ is private
audio.cpp:23: error: within this context
audio.h:10: error: ‘char* audio::stream::Buffer’ is private
audio.cpp:26: error: within this context
audio.h:11: error: ‘size_t audio::stream::BufferSize’ is private
audio.cpp:26: error: within this context
audio.h:11: error: ‘size_t audio::stream::BufferPos’ is private
audio.cpp:27: error: within this context
audio.h:11: error: ‘size_t audio::stream::BufferSize’ is private
audio.cpp:27: error: within this context
audio.cpp: In function ‘mad_flow audio::output(void*, const mad_header*, mad_pcm*)’:
audio.cpp:49: error: new declaration ‘mad_flow audio::output(void*, const mad_header*, mad_pcm*)’
audio.h:15: error: ambiguates old declaration ‘int audio::output(void*, const mad_header*, mad_pcm*)’
audio.cpp: In function ‘mad_flow audio::error(void*, mad_stream*, mad_frame*)’:
audio.cpp:83: error: new declaration ‘mad_flow audio::error(void*, mad_stream*, mad_frame*)’
audio.h:17: error: ambiguates old declaration ‘int audio::error(void*, mad_stream*, mad_frame*)’
audio.cpp: In constructor ‘audio::stream::stream(const char*)’:
audio.cpp:119: error: ‘input’ was not declared in this scope
audio.cpp:122: error: ‘output’ was not declared in this scope
audio.cpp:123: error: ‘error’ was not declared in this scope
make: *** [audio.o] Error 1

audio.h contains

#ifndef _AUDIO_H_
#define _AUDIO_H_

#include <stdlib.h>
#include "mad.h"

namespace audio {
  class stream {
  private:
    char* Buffer;
    size_t BufferSize, BufferPos;
    struct mad_decoder Decoder;

    friend enum mad_flow input(void* Data, struct mad_stream* MadStream);
    friend enum mad_flow output(void* Data, const struct mad_header* Header,
                struct mad_pcm* PCM);
    friend enum mad_flow error(void* Data, struct mad_stream* MadStream,
                   struct mad_frame* Frame);

  public:
    stream(const char* FileName);
    ~stream();

    void play();
  };
}

#endif

Update:

The problem seams to be that mad_flow can't been seen. If I look in mad.h, then mad_flow is declared there.

If I just copy/paste

  enum mad_flow {
    MAD_FLOW_CONTINUE = 0x0000,
    MAD_FLOW_STOP     = 0x0010,
    MAD_FLOW_BREAK    = 0x0011,
    MAD_FLOW_IGNORE   = 0x0020
  };

from mad.h the error goes away (and new errors occur).

So how do I make mad_flow available?

+1  A: 

I downloaded the source archive from https://docs.google.com/leaf?id=0BzqFMbU_9R0YMDI5ZjYzNDAtMTNkZC00YzYwLWE3N2UtYTFmNjdlM2ZiYTg5&amp;hl=en_GB. In the INSTALL, it says:

You need libpng >= 1.0.6, esound-devel and Mesa >= 3.3 to compile this. These can be found at <URI:http://home.online.no/~loop/tsunami.html&gt;. Future update can also be found here.

Make:
make all

Run:
./demo

So make sure you have all the dependencies before you run make all. Unfortunately, the url provided in the INSTALL file is a broken link so you'll have to try to find the listed dependencies elsewhere on the web.

Asaph
I have all those =)
Sandra Schlichting
+2  A: 

Regarding:

I have tried to just insert

enum mad_flow {};

... a correct forward declaration of the type mad_flow would be:

enum mad_flow ;

But you should really be asking yourself why the declaration or definition is not already visible since the forward declaration is probably a bit of a kludge. Are all the necessary headers included?

[---edit---]

In response to Johannes Schaub's comment, here's a compilable example of a forward declared enum:

enum mad_flow ;             // forward declaration

void f( mad_flow& arg ) ;   // forward declaration of function 
                            // using incomplete type

int main()
{
    mad_flow x ;            // Declaration using incomplete type

    f( x ) ;                // Function call using incomplete enum object
}

enum mad_flow               // Completion of the definition
{
    VALUE1,
    VALUE2
} ;

void f( mad_flow& arg )
{
    arg = VALUE1 ;          // Use of value from complete definition
}
Clifford
That's a very good question. The compiler problems I have fixed so far have all been because the programmer have relied on an old version of gcc that did some implicit header inclusion, that the current gcc doesn't do any more.
Sandra Schlichting
You can't forward declare enums, actually.
Johannes Schaub - litb
@Johannes Schaub - litb: Yes you can. I have added a compilable demonstration to the answer.
Clifford
@Clifford Given your code, g++ produces "error: use of enum 'mad_flow' without previous declaration"
anon
@Clifford declaring enums without providing a body is new in C++0x and is called an "opaque enum declaration". Such a declaration nontheless provides a complete enum type, but without making declaring the enumerator list. The list can be declared later. Things like "enum foo;" are completely forbidden because that doesn't specify the underlying type. In C++0x, you have to do "enum foo : int;" for example, and in C++03 all these things won't work.
Johannes Schaub - litb
Interesting. The code I posted works in VC++2008, which makes no claims to C++0x support. Is the required underlying type of an enum not *int*? I believe that it is in ISO C, and assumed it was in C++; it seems at least in VC++2008 it is (although I realise that that is not the arbiter of correctness at all.)
Clifford
@Clifford it's not int in neither C nor C++. What is int in C is the type of the enumerators (like `VALUE1` and `VALUE2` above). What is not int is the underlying type of an object of that enumeration. That is, `sizeof(x) != sizeof(int)` can very well be true even in C.
Johannes Schaub - litb
@Johannes Schaub - litb: Thanks; I see your point. At least I was right about it being a bit of a kludge! ;-) A non-portable kludge at that.
Clifford