Sverker Nilsson said:
Claudio Grondi said:
but the problem with sets.c remains:
C:\VisualC++NET2003\Vc7\bin\cl.exe /c /nologo /Ox /MD /W3 /G7 /GX
/DNDEBUG -IE:\Python24\include -IE:\Python24\PC /Tcsrc/sets/sets.c
/Fobuild\temp.win32-2.4\Re
lease\src/sets/sets.obj
sets.c
src\sets\sets.c(68) : error C2099: initializer is not a constant
src\sets\sets.c(68) : warning C4047: 'initializing' : 'PyTypeObject *'
differs in levels of indirection from 'NyHeapDef_SizeGetter'
src\sets\sets.c(69) : error C2099: initializer is not a constant
src\sets\sets.c(69) : warning C4028: formal parameter 1 different from
declaration
src\sets\sets.c(70) : error C2099: initializer is not a constant
src\sets\sets.c(70) : warning C4047: 'initializing' : 'PyTypeObject *'
differs in levels of indirection from 'int (__cdecl *)(PyObject *)'
src\sets\sets.c(70) : warning C4028: formal parameter 1 different from
declaration
src\sets\sets.c(70) : warning C4028: formal parameter 1 different from
declaration
error: command 'E:\VisualC++NET2003\Vc7\bin\cl.exe' failed with exit status
2
The MSDN help gives a simple example of code raising compiler error C2099:
// C2099.c
int j;
int *p;
j = *p; // C2099, *p is not a constant
The example code shows to me, that there is a good reason compiler
generates an error in that case.
j = *p; leads to an assignment of a random (and therefore maybe leading to a
non deterministic crash of the executable during runtime) value to a
variable, what can't be intended in a deterministic program.
This is confusing, because the problem of the example code is not that
*p is not constant but rather that p is undefined aka uninitialized.
Humm..
Compiling the following program:
#include <stdio.h>
int main(void) {
int j;
int *p;
j = *p;
printf("%d\n",j); /* Makes sure the optimizer doesnt remove the
previous code */
return 0;
}
with
gcc -O3 -Wall main.c
gives me:
main.c: In function `main':
main.c:4: warning: `p' might be used uninitialized in this function
(And I get a Segmentation fault from running the executable.)
The -Wall flag enables, umm, as it is saying 'all' warnings
though perhaps not really all, and this flag + others is used
by the compilation command generated by distutils when
building with gcc.
I don't see any warnings when building Guppy.
So there should be no case (as easy to discover) as that in the
example.
So I am confused.
I was beginning to wonder if we were talking about the same file/code.
This code is from sets.c lines 66..71
static NyHeapDef nysets_heapdefs[] = {
{0, &NyMutBitSet_Type, (NyHeapDef_SizeGetter) mutbitset_indisize},
{0, &NyCplBitSet_Type, 0, cplbitset_traverse},
{0, &NyNodeSet_Type, nodeset_indisize, nodeset_traverse,
nodeset_relate},
{0}
};
The code in my sets.c file is lines 67..72:
static NyHeapDef nysets_heapdefs[] = {
{0, &NyMutBitSet_Type, (NyHeapDef_SizeGetter) mutbitset_indisize},
{0, &NyCplBitSet_Type, 0, cplbitset_traverse},
{0, &NyNodeSet_Type, nodeset_indisize, nodeset_traverse,
nodeset_relate},
{0}
};
Maybe you can explain what this declaration is good for and where the
identifiers are defined, so that I have a chance to fix it myself?
Currently I have no idea where to start and what is wrong with it.
It seems, that the only one not declared identifier is NyHeapDef_SizeGetter,
but this does not help because if I preceede the code with
extern NyHeapDef_SizeGetter
I get:
src\sets\sets.c(68) : warning C4091: 'extern ' : ignored on left of 'int
(__cdecl *)(PyObject *)' when no variable is declared
src\sets\sets.c(78) : error C2099: initializer is not a constant
src\sets\sets.c(78) : warning C4047: 'initializing' : 'PyTypeObject *'
differs in levels of indirection from 'NyHeapDef_SizeGetter'
src\sets\sets.c(79) : error C2099: initializer is not a constant
src\sets\sets.c(79) : warning C4028: formal parameter 1 different from
declaration
src\sets\sets.c(80) : error C2099: initializer is not a constant
src\sets\sets.c(80) : warning C4047: 'initializing' : 'PyTypeObject *'
differs in levels of indirection from 'int (__cdecl *)(PyObject *)'
src\sets\sets.c(80) : warning C4028: formal parameter 1 different from
declaration
src\sets\sets.c(80) : warning C4028: formal parameter 1 different from
declaration
error: command 'E:\VisualC++NET2003\Vc7\bin\cl.exe' failed with exit status
2
where the code at line 68 is:
extern NyHeapDef_SizeGetter; // line 68
// extern mutbitset_indisize;
// extern NyCplBitSet_Type;
// extern cplbitset_traverse;
// extern NyNodeSet_Type;
// extern nodeset_indisize;
// extern nodeset_traverse;
// extern nodeset_relate;
static NyHeapDef nysets_heapdefs[] = {
{0, &NyMutBitSet_Type, (NyHeapDef_SizeGetter) mutbitset_indisize},
{0, &NyCplBitSet_Type, 0, cplbitset_traverse},
{0, &NyNodeSet_Type, nodeset_indisize, nodeset_traverse,
nodeset_relate},
{0}
};
I can't see how there can be problems with initializers not being
constants here unless, perhaps if the compiler has a problem since
those functions (mutbitset_indisize etc) and the types that are used
as initializers are in separately compiled files. But gcc -Wall
-pedantic handles it and doesn't warn. I don't have the ANSI standard
but I have the 2nd edition of The C Programming Language by Kernighan
and Ritchie (1988, 'Based on Draft-Proposed ANSI C'), and it is saying
- quotes -
A8.7 Initialization
...
All the expressions in the initializer for a static object or array
must be constant expressions as described in &A7.19
...
A7.19 Constant Expressions
Syntactically, a constant expression is an expression restricted to a
subset of operators...
...
More latitude is permitted for the constant expressions of
initializers... Initializers must evaluate either to a constant or to
the address of a previously declared external or static object plus or
minus a constant.
- end quotes -
If this means the Microsoft .NET compiler is perhaps not compliant
with standard/ANSI C then since it was from 2003 maybe they have come
out with an update now that fixes this problem. I know, it may not
really help you because it may cost money, I don't know how long one
can get updates without paying. Alternatively, I think GCC is
available for Microsoft Windows although I don't know how it handles
the .NET architecture.
For me, if the case is according to hypothesis, and I would have to
rewrite the code to put all the functions and type objects in a single
file, it would be.. umm.. painful. (Though I could get around
it with #include trickery but it is still painful.)
Sverker
I don't know if it applies here, but in this context the extern keyword
comes to my mind.
Here is what MSDN says about it:
The extern keyword declares a variable or function and specifies that it has
external linkage (its name is visible from files other than the one in which
it's defined). When modifying a variable, extern specifies that the variable
has static duration (it is allocated when the program begins and deallocated
when the program ends). The variable or function may be defined in another
source file, or later in the same file. Declarations of variables and
functions at file scope are external by default.
Maybe it helps?
Claudio