Maybe OT, compiles in DevCPP, not in MSVC 2008

J

Jim Langston

I'm trying to compile some source code to interface LUA into C++. When I
compile in MSVC++ Express 2008, however, I get the error (among others):

....\luastate.h(129) : error C2027: use of undefined type
'cpplua::LuaFunction'
....\luastate.h(63) : see declaration of 'cpplua::LuaFunction'

So I'm trying to track this down. I see that there is a function trying to
return LuaFunction Like this:

LuaFunction createFunction(cppluaFunction* f);
template <typename T> LuaFunction createFunction(T& object,
int(T::*f)(LuaState*)) {
LuaFunction res = createFunctionFromObject();
lua_pushlightuserdata(L, &res);
lua_pushlightuserdata(L, reinterpret_cast<void*>(&object));
void* ptmf = lua_newuserdata(L, sizeof(int(T::*)(LuaState*)));
std::memcpy(ptmf, &f, sizeof(int(T::*)(LuaState*)));
lua_pushcclosure(L, LuaState::generalTemplateFunction<T>, 2);
lua_settable(L, cppluaTableIndex);
return res;
}

And the error is showing up on the closing bracket which is line 129. So
then I try to back track where LuaFunction is defined and find in some
unrelated class:
friend class LuaFunction;

The I try to find out if luafunction.h is included, and it is, but in a roud
about way. I find there are some interdepedancies between luastate.h and
luafunction.h

luafuncion.h includes
luaobject.h which includes
luastate.h

before any other custom headers in each.

luastate.h, however, does not include luafunction.h

luastate.cpp incluses luastate.h before any other header.

So how the heck does DevCPP compile this mess? At the point of luastate.h
line 129 LuaFunction has not been declared. Yet DevCPP goes ahead and
compiles it happily.

Unfortuanlly, the project I eventually want to use this lua interface in is
a MSVC++ 2008 project and the lua library I have is for microsoft (it failes
with many errors linking in DevCPP).

What is the culprit here? I'm suspecting it some DevCPP "extention"
although not thought of as that, as DevCPP just goes ahead and figures out
how to compile it somehow when logically it shouldn't. There are so many
interdependancies in thsi code that to fix it might to do.

Any help would be appreciated.
 
J

James Kanze

I'm trying to compile some source code to interface LUA into
C++. When I compile in MSVC++ Express 2008, however, I get
the error (among others):
...\luastate.h(129) : error C2027: use of undefined type
'cpplua::LuaFunction'
...\luastate.h(63) : see declaration of 'cpplua::LuaFunction'
So I'm trying to track this down. I see that there is a
function trying to return LuaFunction Like this:
LuaFunction createFunction(cppluaFunction* f);
template <typename T> LuaFunction createFunction(T& object,
int(T::*f)(LuaState*)) {
LuaFunction res = createFunctionFromObject();
lua_pushlightuserdata(L, &res);
lua_pushlightuserdata(L, reinterpret_cast<void*>(&object));
void* ptmf = lua_newuserdata(L, sizeof(int(T::*)(LuaState*)));
std::memcpy(ptmf, &f, sizeof(int(T::*)(LuaState*)));
lua_pushcclosure(L, LuaState::generalTemplateFunction<T>, 2);
lua_settable(L, cppluaTableIndex);
return res;
}

Supposing that what the compiler really means by "undefined
type" is what is called an incomplete type in the standard. If
LuaFunction is an incomplete type at this point, then "If a type
used in a non-dependent name is incomplete at the point at which
a template is defined but is complete at the point at which an
instantiation is done, and if the completeness of that type
affects whether or not the program is well-formed or affects the
semantics of the program, the program is ill-formed; no
diagnostic is required." (This is from my copy of the C++03
standard, where it is marked as an insertion, in response to
core issue 206. This sentence isn't present in C++98, but
presumably, it was the intent.)
And the error is showing up on the closing bracket which is
line 129. So then I try to back track where LuaFunction is
defined and find in some unrelated class:
friend class LuaFunction;

Which doesn't make the name visible outside of that class.
The I try to find out if luafunction.h is included, and it is,
but in a roud about way. I find there are some
interdepedancies between luastate.h and luafunction.h
luafuncion.h includes
luaobject.h which includes
luastate.h
before any other custom headers in each.

Which means anything defined in luastate.h cannot use the
contents of luaobject.h or luafuncion.h, since luastate.h will
be included before the bodies of those headers.
luastate.h, however, does not include luafunction.h

And it wouldn't change anything if it did, supposing that all of
the .h files have header guards. (Without any header guards, if
luastate.h included luafunction.h, and luafunction.h included
luastate.h, you'd have an infinite inclusion. Undefined
behavior, but almost certainly either a compiler error or a
compiler crash.)
luastate.cpp incluses luastate.h before any other header.
So how the heck does DevCPP compile this mess? At the point
of luastate.h line 129 LuaFunction has not been declared. Yet
DevCPP goes ahead and compiles it happily.

A lot of older compilers treated templates more or like macros.
They barely parsed them enough to know where they ended where
the template was defined, and only really did any analysis when
the template was instantiated. I suppose that LuaFunction *is*
fully defined when the function is instantiated. (And of
course, regardless of how templates are instantiated, the
compiler doesn't really need the complete definition of
LuaFunction until it starts generating code, and it won't start
generating code until there is an instantiation.)

Note that this technique is still legal. The standard specified
templates in a way that allowed the compiler to detect a good
number of errors in the templates definition, but all of these
errors are considered "undefined behavior"---the compiler is not
required to diagnose them. (The standard really needs another
category for this: either the compiler diagnoses an error, or
the code works. There are a number of such cases in the
standard, and classifying them as "undefined behavior" is
overdoing it, IMHO.)
Unfortuanlly, the project I eventually want to use this lua
interface in is a MSVC++ 2008 project and the lua library I
have is for microsoft (it failes with many errors linking in
DevCPP).
What is the culprit here? I'm suspecting it some DevCPP
"extention" although not thought of as that, as DevCPP just
goes ahead and figures out how to compile it somehow when
logically it shouldn't. There are so many interdependancies
in this code that to fix it might to do.

Not so much an "extention", I think, but simply an artifact of
the compiler's age (or a simplification in the implementation of
the compiler). And while I can't quite parse your last
sentence, you are going to have to fix some of the dependencies.
I don't think that there's any other way around it. (Note that
one solution that sometimes helps is to declare the functions,
*then* include the headers needed for their implementation, then
define them. Or to put the declarations and the definitions in
separate header files; the client headers will then include
first all of the declarations they need, then all of the
definitions.)
 

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

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,065
Latest member
OrderGreenAcreCBD

Latest Threads

Top