2

I am trying to implement a Websocket Server. I am using the libwebsockets library.

ConnectionServer.c file has setup code for the library and main() function (I don't see anything of importance to post here.) This file includes 1 file for the received data callback called: dmserver_callback.cpp. This file then includes another file (my custom parser file) called: data_parser.cpp. This file then includes a file called definitions.h (the source of the problem).

Just bear with me; I understand that including files (daisy chaining; so to speak) probably isn't the best way to do this, and I more than likely should be using header files and such. One question I have is that is this particularly necessary?

To clarify, everything is working as intended until I try to add my own parsing mechanism.

The definitions.h file is as follows:

namespace EngineDefinitions {
enum Version {
    Major = 1,
    Minor = 2
}; //Version;

namespace Server {
    enum enum_Server {
        MAX_PLAYERS = 200,
        MAX_TABLES = 42, // 3 tables per row.
        MAX_TABLE_PLAYERS = 10,
        GAME_PORT = 2040, //2042
        MAX_PARAMS = 10
    }; //Server;
};

namespace Login {
    enum enum_Login {
        USERNAME = 1,
        PASSWORD = 2
    }; //Login;
};
};

My error is:

definitions.h(1): error C2061: syntax error : identifier 'EngineDefinitions'

I loaded the exact same header in a new Win32 Console Project in Visual C++ 2010 Express and there it works. The only difference I see is the main file (where int main function resides). In the project that the header file works is called: ConectionServer.cpp (C++)

and the main project file that doesn't work is named: ConnectionServer.c (C)

Does this have something to do with the file being compiled in C vs C++?

I think that the libwebsocket library is coded in C. I can't recall if I created the project files in exactly the same manner or not.

P.S. Please let me know if there is any other information I can provide to help.

EDIT: I also realize you're not supposed to define types inside a header file (eg: enums). I DID try to separate the source into .cpp and a header file using the extern enum with no difference. In fact, got more errors (redefinitions) than I bargained for when trying to use them.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Levi Roberts
  • 1,277
  • 3
  • 22
  • 44
  • You really shouldn't be including `.cpp` files. – Marlon Mar 06 '12 at 04:52
  • Yes, I understand that I shouldnt be including the files this way. As I mentioned, even if I use the header files appropriately, I still get this error in the first project however not the second. – Levi Roberts Mar 06 '12 at 04:57
  • 1
    You need to understand that C++ and C are different languages. When you include the header file in a `.cpp` file, the compiler will try to compile the `.h` as C++ code. C++ supports namespaces, so everyone is happy. But when you try to include the `.h` from the `.c` file (which is what is actually happening if you follow the `#include`s), the compiler attempts to compile the `.h` as C code, yet fails because namespaces do not exist in C. No one is happy. – Marlon Mar 06 '12 at 04:59
  • Now this is starting to make sense. Ill attempt to compile as C++ and see what comes of it. Thank you. – Levi Roberts Mar 06 '12 at 05:03
  • 1
    Where did you get the idea the types should not be defined in headers? If the type is needed in more than one source file, then a header is exactly where it should be defined, and is the only place the type should be defined. If the type is needed only in one file, then it does not belong in a header, usually, unless you are forward planning (but then the Agile folks say 'YAGNI', "You ain't gonna need it"). Headers should be used primarily for sharing common information (types and function - and, if necessary, variable - declarations). Everything else should be kept in the source files. – Jonathan Leffler Mar 06 '12 at 05:04
  • Perhaps I dont have the correct terminology. I understand you can define the type but your not suppose to initialize it with data in a header. In the case of header file code: int myInt; is proper, however int myInt = 3; is not proper in a header. – Levi Roberts Mar 06 '12 at 05:07

3 Answers3

7

You need to understand that C++ and C are different languages. When you include the header file in a .cpp file, the compiler will try to compile the .h as C++ code. C++ supports namespaces, so everyone is happy. But when you try to include the .h from the .c file (which is what is actually happening if you follow the #includes), the compiler attempts to compile the .h as C code, yet fails because namespaces do not exist in C.

A common way to solve this problem is to use predefined macros. __cplusplus is defined when compiling as C++ code, and not defined when compiling as C code (obviously).

You could do this:

#ifdef __cplusplus
namespace EngineDefinitions {
#endif
enum Version {
    Major = 1,
    Minor = 2
}; //Version;

#ifdef __cplusplus
namespace Server {
#endif
    enum enum_Server {
        MAX_PLAYERS = 200,
        MAX_TABLES = 42, // 3 tables per row.
        MAX_TABLE_PLAYERS = 10,
        GAME_PORT = 2040, //2042
        MAX_PARAMS = 10
    }; //Server;
#ifdef __cplusplus
};
#endif

#ifdef __cplusplus
namespace Login {
#endif
    enum enum_Login {
        USERNAME = 1,
        PASSWORD = 2
    }; //Login;
#ifdef __cplusplus
};
#endif

And of course, you lose the ability of namespaces in C anyways.

Marlon
  • 19,924
  • 12
  • 70
  • 101
  • 2
    You need to be extra super-duper careful with naming clashes if you do this. Putting something like `Version` or `Major` in the root namespace might not be a good plan when compiling the code as C. – Cody Gray - on strike Mar 06 '12 at 05:06
  • This is the best answer so far so I marked it as so. The best solution for my problem is to just convert the project to C++. Also, as a note, I do understand that they are different languages but had no way of knowing what the project was set to since both projects open with Visual C++. I was under the assumption that this was my problem - sorry if I didnt make that apparent. – Levi Roberts Mar 06 '12 at 05:15
  • An update: I just finished updating the project to C++ and everything is now working just as intended. You pretty much spotted exactly what it was doing. The compiler was trying to compile the program as C when C++ was needed for the namespace. Appreciate the help. – Levi Roberts Mar 06 '12 at 05:39
5

C does not have namespaces. For Real.

Joe
  • 2,946
  • 18
  • 17
1

You cannot include a C++ file in a C file (unless it has been prepared for such use). If you then try to compile the C file, it'll try to compile even the C++ file as C. Instead, use separate compilation and header files.

Note that C does not understand namespaces.

ibid
  • 3,891
  • 22
  • 17
  • 1
    @Levi: Sounds like it's time to pick up [a good book about C++ programming](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Cody Gray - on strike Mar 06 '12 at 05:03