Urgent help needed with cryptic VC++ error messages

Dear ROOTers,

After successfully compiling my program with MacOS X Snow Leopard and with OpenSUSE11.3 I wanted to compile it with VC++, too, but got cryptic error messages which I do not understand. I do not even know where to look because there are either no lines given or the line numbers do not make any sense. Here is the error message:

XPSPreProcessing.cxx
XPSPreProcessing.cxx(2784) : error C2090: function returns array
XPSPreProcessing.cxx(2784) : error C2528: '__iob_func' : pointer to reference is illegal
XPSPreProcessing.cxx(2784) : error C2556: 'Double_t ***__iob_func(void)' : overloaded function d
iffers only by return type from 'FILE *__iob_func(void)'
        C:\Programme\Microsoft Visual Studio 9.0\VC\INCLUDE\stdio.h(132) : see declaration of '_
_iob_func'
XPSPreProcessing.cxx(2784) : error C2072: '__iob_func' : initialization of a function
XPSPreProcessing.cxx(2784) : error C2205: '__iob_func' : cannot initialize extern variables with
 block scope
XPSPreProcessing.cxx(2784) : error C2440: 'initializing' : cannot convert from 'int' to 'Double_
t ***(void)'
        There are no conversions to function types, although there are conversions to references
 or pointers to functions
XPSPreProcessing.cxx(2875) : error C2440: '=' : cannot convert from 'Double_t *' to 'Double_t **
*'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or fu
nction-style cast
XPSPreProcessing.cxx(2890) : error C2440: '=' : cannot convert from 'double' to 'Double_t **'
XPSPreProcessing.cxx(3147) : error C2664: 'Int_t XAlgorithm::Calculate(Int_t,Double_t *,Double_t
 *,Double_t *,Int_t *,Int_t *)' : cannot convert parameter 3 from 'Double_t ***' to 'Double_t *'

        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or fu
nction-style cast
XPSPreProcessing.cxx(3186) : error C2665: 'TStat::Median' : none of the 4 overloads could conver
t all the argument types
        c:\home\rabbitus\temp\rtmpjepftp\r.install31a85835\xps\src\TStat.h(114): could be 'Doubl
e_t TStat::Median(Int_t,const Double_t *,const Int_t *)'
        c:\home\rabbitus\temp\rtmpjepftp\r.install31a85835\xps\src\TStat.h(116): or       'Doubl
e_t TStat::Median(Int_t,const Double_t *,UShort_t)'
        while trying to match the argument list '(Int_t, Double_t ***, int)'
XPSPreProcessing.cxx(3195) : error C2665: 'TMath::Abs' : none of the 6 overloads could convert a
ll the argument types
        c:\root\include\TMathBase.h(36): could be 'Short_t TMath::Abs(Short_t)'
        c:\root\include\TMathBase.h(37): or       'Int_t TMath::Abs(Int_t)'
        c:\root\include\TMathBase.h(38): or       'Long_t TMath::Abs(Long_t)'
        c:\root\include\TMathBase.h(39): or       'Long64_t TMath::Abs(Long64_t)'
        c:\root\include\TMathBase.h(40): or       'Float_t TMath::Abs(Float_t)'
        c:\root\include\TMathBase.h(41): or       'Double_t TMath::Abs(Double_t)'
        while trying to match the argument list '(Double_t **)'
XPSPreProcessing.cxx(3197) : error C2664: 'TMath::Log2' : cannot convert parameter 1 from 'Doubl
e_t **' to 'Double_t'
        There is no context in which this conversion is possible
XPSPreProcessing.cxx(3270) : error C2106: '=' : left operand must be l-value
make: *** [XPSPreProcessing.obj] Error 2
ERROR: compilation failed for package 'xps'

Enclosed I am attaching file “XPSPreProcessing.cxx”. Please note that earlier versions of this file compiled fine with VC++, thus the problems must be in one of the new functions:

      virtual Int_t QualityControl(Int_t numdata, TTree **datatree,
                       Int_t numbgrd, TTree **bgrdtree, const char *option);
      virtual Int_t DoDataQualityControl(Int_t numdata, TTree **datatree,
                       TTree **resdtree, TTree **exprtree,
                       XDNAChip *chip, TFile *file);
      virtual Int_t DoBorderElements(Int_t numdata, TTree **datatree,
                       TTree **bordtree, XDNAChip *chip, TFile *file);
      virtual Int_t DoBgrdQualityControl(Int_t numbgrd, TTree **bgrdtree,
                       XDNAChip *chip, TFile *file);

I would greatly appreciate any help, since I do not know where to look and there are no lines given by VC++.

Thank you very much.
Best regards
Christian
XPSPreProcessing.cxx (361 KB)

Can you give the full code which compiles on mac and has errors on Windows?
Guess work is not very interesting.

Right now what I can see, for example, you use variable with a name stderr.

In <stdio.h>, stderr is defined as #define stderr (&__iob_func()[2]),
so you have

double * (&__iob_func()[2]),

in this syntax construct, for example
__iob_func is a name, () means it’s a function, [2] means it’s a function returning array.

Etc.

So, for this small program:

#include <cstdio>

int main()
{
    double * stderr = 0;
}

I got the following errors:

Thank you very much, this is already very helpful. I will change the name of stderr and let you know the result.

Now that you explained this I am wondering why both Mac and Linux do not report that stderr is already defined in stdio.h.

Best regards
Christian

[quote=“cstrato”]
Now that you explained this I am wondering why both Mac and Linux do not report that stderr is already defined in stdio.h.

Best regards
Christian[/quote]

For example:

int stdERR;

void fun()
{
     double stdERR;
}

For another example, stdio.h:

/* Standard streams.  */
extern struct _IO_FILE *stdin;          /* Standard input stream.  */
extern struct _IO_FILE *stdout;         /* Standard output stream.  */
extern struct _IO_FILE *stderr;         /* Standard error output stream.  */
#ifdef __STDC__
/* C89/C99 say they're macros.  Make them happy.  */
#define stdin stdin
#define stdout stdout
#define stderr stderr
#endif

So, of course in a scope other than global you can redeclare this name. Even in a global scope you can declare another entity (of different kind) with the same name, for example:

int A;

struct A
{
};

int main()
{
}

Renaming “stderr” to “sterr” allowed me to successfully compile my program with VC++.
Thank you very much for your fast help, I really appreciate it.

Although I understand your explanation, it is nevertheless not clear to me why VC++ reports an error message while the identical code compiles even w/o warning on Linux/Mac.

Best regards
Christian

[quote=“cstrato”]Renaming “stderr” to “sterr” allowed me to successfully compile my program with VC++.
Thank you very much for your fast help, I really appreciate it.
[/quote]

You are welcome! :slight_smile:

[quote]
Although I understand your explanation, it is nevertheless not clear to me why VC++ reports an error message while the identical code compiles even w/o warning on Linux/Mac.

Best regards
Christian[/quote]

Easy: in case of VC++, stderr is a macro, which (as I demonstrated in my first answer) is expanded into some expression (and it’s OK according to C99 language standard). Macro is something orthogonal to scopes, so it effects your local variable with the same name, converting it into illegal function declaration.
In case of g++/gcc and its standard library (as I also demonstrated), stderr is a pointer and the macro with the same name:

extern struct _IO_FILE *stderr;         /* Standard error output stream.  */
#ifdef __STDC__
#define stderr stderr
#endif

So, even if preprocessor expands stderr macro in your local variable declaration, you still got

void your_fun()
{
   ....
   double * stderr;
   .....
}

in the block-scope, and this declaration hides global declaration and this is ok.

In fact, thank you. You demonstrated quite interesting thing: it’s impossible to use the name ‘stderr’ for you own entities in a C++ program, which wants to be cross-platform. And as soon as stderr macro from C library is also part of C++ standard library, it becomes a reserved name.

Thank you for this explanation, now I understand.

Best regards
Christian