Sign in to follow this  
L. Spiro

#include iostream Error

Recommended Posts

L. Spiro    25622
I created a new shader language using Flex/Bison.
Flex generated files #include <iostream>, and this worked fine until I finally hooked the new shader system up to the rest of the engine. Some files (but only those in the main engine library) give me the following error:

1>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(131) : error C2143: syntax error : missing ';' before '*'
1>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(131) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(131) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
1>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(188) : error C2065: '_File' : undeclared identifier
1>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(188) : warning C4229: anachronism used : modifiers on data are ignored
1>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(188) : fatal error C1903: unable to recover from previous error(s); stopping compilation


Those lines of code are, respectively:
#ifndef _STDIO_DEFINED
_CRTIMP FILE * __cdecl __iob_func(void); // Line 131
#endif /* _STDIO_DEFINED */



#ifndef _STDIO_DEFINED

_CRTIMP __checkReturn int __cdecl _filbuf(__inout FILE * _File ); // Line 188[/code]



This error only happens in the top-level engine module (the main one that brings together all others).
Modules that do not need to know about each other don’t.
The graphics library has no problem when it includes a shader object. By including a shader object, you will get the <iostream> included by Flex.
Not only this, but the model editor tool, which builds as a separate executable but links to the main engine libraries, served as my testbed for building the shader language.
From that executable, I was perfectly able to include all of the engine files and then include the shader files, and had no problems building from there.

Only certain files throw this error, all from the main engine module, and I cannot find the reason why.
With certainty, it is possible to include the whole engine (when the shader files were part of the engine but not included by any part of the engine), then include the shaders. This is how I developed the shaders, including them manually from my model editor.

This error only started happening when my shader language was done and it was time to hook it up to the engine directly to make actual use of it.
As soon as it was being #include’d by some parts of the engine, top-level parts of the engine started throwing this error.
This tells me that this really has to do with the order of the #include’s (my #include’s are always alphabetical).

Unfortunately, there are 681 code files in the engine, and the files throwing this error include so many files that include so many files, there is no way for me to track down exactly which order is bad.



Let me ask here: What could cause this error given that it is 100% sure to result from #include <iostream>?
Is there something that MUST be included before <iostream>?
Is there something that MUST be included after it?


Here are the other files included by the engine (on Windows) (in no particular order):
#include <windows.h>
#include <new>
#include <cassert>
#include <winerror.h>
#include <tchar.h>
#include <string> // By Flex/Bison.
#include <algorithm> // By Flex/Bison.
#include <deque> // By Flex/Bison.
#include <gl/gl.h>
#include "glu.h"
#include "glext.h"
#include <cmath>


I do not see anything that could possibly clash with <iostream>.
#include <cstdlib> and #include <shlwapi.h> are the only others, but they are included in .cpp files, and are not related to this error; from the viewpoint of the files that get an error, these files have no possibility of being #include’d.

All I can say for sure is that, in the problematic files, <windows.h> is always included prior to <iostream>.
And my way of including it:

// Set the Windows version.
#ifndef WINVER
#define WINVER 0x0501
#endif
#ifndef _WIN32_WINDOWS
#define _WIN32_WINDOWS 0x0501
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif

#define NOMINMAX // We do not want min/max as macros.
#include <windows.h>



Any ideas?


Yogurt Emperor

Share this post


Link to post
Share on other sites
MaulingMonkey    1728
Quote:
Original post by YogurtEmperor
Let me ask here: What could cause this error given that it is 100% sure to result from #include <iostream>?
Is there something that MUST be included before <iostream>?
Is there something that MUST be included after it?

No to both. Possible things to blame include missing semicolons (usually resulting in errors in whatever files get #included after them) and evil #defines.

Quote:
All I can say for sure is that, in the problematic files, <windows.h> is always included prior to <iostream>.
And my way of including it:

// Set the Windows version.
#ifndef WINVER
#define WINVER 0x0501
#endif
#ifndef _WIN32_WINDOWS
#define _WIN32_WINDOWS 0x0501
#endif
#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif

#define NOMINMAX // We do not want min/max as macros.
#include <windows.h>



Any ideas?


This probably won't help, but all these #defines belong in your project settings. If anything ever #includes <windows.h> on your behalf or you manage to forget to do this once, the inconsistent #defines can cause trouble. Setting these in your project settings instead avoids the pain of having to do this repeatedly and makes it much more difficult to screw up.

Share this post


Link to post
Share on other sites
L. Spiro    25622
Yes, I agree with the synchronization of those defines, but my solution was instead to make LSEWin32.h, which has that code in it.
Then any files that need windows.h will instead include that file.

So I will not have any problems there.

And my reason for not using project settings? Because my engine is actually about 16 libraries, each its own project, linked together to form the final engine library.
If I had to set those values in the compiler options it would be just as risky, plus tons of work.


Besides, my engine runs on Windows (x86 and x64), iPhone, Nintendo Wii, PlayStation 3, Xbox 360, Linux, and Macintosh OSX. Only very very few files will ever reach an #include <windows.h>, as this design is intended to be very portable and rely on as few OS API routines as possible.


That aside I have more information on the bug.






Here is the story:
I made a new shader language for my engine (because my engine runs on every platform, and there are no shader languages that exist with this much support).
My engine, as mentioned, is built as 16 different libraries, very modular and organized, with one major library (named LSE) at the top which brings every other library together in a logical way.
Then I have a model editor, which links to the library, of course #including all of its major files.
While I was developing the shader language, I was just using #include "LSGShader.h" (LSG = L. Spiro Graphics, the graphics library of the engine) so I could test the shader language as I developed it. When I #include "LSGShader.h", it eventually includes a file generated by Flex which #include <iostream>’s. It is a C++ Flex scanner.
When I was done it was time to hook up the shader (and the shader language) to the engine so that the engine could use it.
As soon as I added #include "LSGShader.h" to the LSG library, the LSE library broke (with the error above).

Well this was strange, because the LSG library had no problem with #include "LSGShader.h", and neither did the model editor, which included both LSG and LSE, AND LSGShader.h.

Remember, the engine is a bunch of libraries that are each their own projects.
The LSG project and the model editor were both able to get that #include <iostream> without a problem. Only when that line was reached from the LSE library was there a problem.


So I precompiled the translation unit from LSE that gave the first error.
14>LSECoreParticleManager3.cpp
14>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(131) : error C2143: syntax error : missing ';' before '*'
14>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(131) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
14>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(131) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int
14>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(188) : error C2065: '_File' : undeclared identifier
14>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(188) : warning C4229: anachronism used : modifiers on data are ignored
14>D:\Programs\Microsoft Visual Studio 8\VC\include\stdio.h(188) : fatal error C1903: unable to recover from previous error(s); stopping compilation


If I go to stdio.h line 131, I see this:
_CRTIMP FILE * __cdecl __iob_func(void);

Basically the error means that FILE is not defined here. Well, this is frankly impossible.

So I checked my precompiled output:
#line 131 "D:\\Programs\\Microsoft Visual Studio 8\\VC\\include\\stdio.h"
FILE * __cdecl __iob_func(void);


This confirms that FILE is indeed defined here, starting at the translation unit “LSECoreParticleManager3.cpp”
And this confirms that it should be entirely possible to #include <iostream> from this .CPP file (or any).


The precompiled file is here:
http://memoryhacking.com/Misc/Temp.cpp
See for yourself.


I am using Microsoft Visual Studio 2005, Service Pack 1 (KB926601)
Version 8.0.50727.762 (SP.050727-7600)





The LSG project is fully capable of #include "LSGShader.h", which in turn does #include <iostream>.
Back to LSE:

LSECoreParticleManager3.cpp is the first file to (eventually) #include <iostream> (through LSGShader.h).
It begins like this:


#include "LSECoreParticleManager3.h"
#include "../Scene/LSESceneWorld.h"


namespace lse {

Using this, I get the error I mentioned above.


But when I change it to this:
#include <iostream>
#include "LSECoreParticleManager3.h"
#include "../Scene/LSESceneWorld.h"


namespace lse {

There are no compiler errors!!


I can #include <iostream> from this translation unit, but the order matters somehow.

What can be wrong here?
My preprocessed file of LSECoreParticleManager3.cpp above shows that FILE is indeed defined, but somehow the compiler is chocking on something and messing things up.


Any ideas at all what could cause this?


Thank you,
Yogurt Emperor

Share this post


Link to post
Share on other sites
L. Spiro    25622
Since I was able to #include <iostream> at the start of that .CPP file, I decided to insert an #include <iostream> between each header it included until it no longer worked.

Then I entered the last header that worked and continued the process.

I finally found the exact line that made the difference between a working #include <iostream> and a broken one.

Over a year ago I had an #include <tchar.h> that had been accidentally placed inside the lse namespace.


It happened as a result of updating old code, and I had forgotten that I was in the namespace at the time.
I would never intentionally #include inside a namespace.


This little bomb waited for over a year to explode, hence my confusion.
Moving tchar.h out of the lse namespace fixed everything.
::FILE was not defined, but lse::FILE was, accidentally.


Everything is back to perfect now.


L. Spiro

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this