Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Debugging a template. I'm stuck!

110 views
Skip to first unread message

DSF

unread,
Jan 25, 2015, 2:28:21 PM1/25/15
to
Hello, group!

I have a template class that requires "==" to be overloaded in any
class that uses it. If the class doesn't overload "==", I get the
compile time message "Illegal structure operation" on the "=="
comparison line. This is the error I am receiving. I have gone
through the entire project and every class is never used with the
template class or has "==" overloaded.

If it were a runtime error, I could track down the class involved.
But as it stands, I'm stuck! Any ideas on how to track down this
error?

Thanks,
DSF
"'Later' is the beginning of what's not to be."
D.S. Fiscus

Ian Collins

unread,
Jan 25, 2015, 2:33:16 PM1/25/15
to
DSF wrote:
> Hello, group!
>
> I have a template class that requires "==" to be overloaded in any
> class that uses it. If the class doesn't overload "==", I get the
> compile time message "Illegal structure operation" on the "=="
> comparison line. This is the error I am receiving. I have gone
> through the entire project and every class is never used with the
> template class or has "==" overloaded.

You need to provide more detail - example code that fails to compile and
the exact error message.

--
Ian Collins

Bo Persson

unread,
Jan 26, 2015, 6:39:15 AM1/26/15
to
On 2015-01-25 20:28, DSF wrote:
> Hello, group!
>
> I have a template class that requires "==" to be overloaded in any
> class that uses it. If the class doesn't overload "==", I get the
> compile time message "Illegal structure operation" on the "=="
> comparison line. This is the error I am receiving. I have gone
> through the entire project and every class is never used with the
> template class or has "==" overloaded.
>
> If it were a runtime error, I could track down the class involved.
> But as it stands, I'm stuck! Any ideas on how to track down this
> error?
>

It might be a namespace problem. If the operator== is not in the same
namespace as its class, the compiler will not find it.


Bo Persson


Tobias Müller

unread,
Jan 26, 2015, 12:37:40 PM1/26/15
to
DSF <nota...@address.here> wrote:
> Hello, group!
>
> I have a template class that requires "==" to be overloaded in any
> class that uses it. If the class doesn't overload "==", I get the
> compile time message "Illegal structure operation" on the "=="
> comparison line. This is the error I am receiving. I have gone
> through the entire project and every class is never used with the
> template class or has "==" overloaded.
>
> If it were a runtime error, I could track down the class involved.
> But as it stands, I'm stuck! Any ideas on how to track down this
> error?

Usually the compiler error message tells you that and more:
- the full template type
- all template parameters
- point of instatiation
etc

What compiler are you using?

Tobi

Paavo Helde

unread,
Jan 26, 2015, 2:51:22 PM1/26/15
to
DSF <nota...@address.here> wrote in
news:legacatjsgoujsmd8...@4ax.com:

> Hello, group!
>
> I have a template class that requires "==" to be overloaded in any
> class that uses it. If the class doesn't overload "==", I get the
> compile time message "Illegal structure operation" on the "=="
> comparison line. This is the error I am receiving. I have gone
> through the entire project and every class is never used with the
> template class or has "==" overloaded.
>
> If it were a runtime error, I could track down the class involved.
> But as it stands, I'm stuck! Any ideas on how to track down this
> error?

My crystal ball tells me you are missing 'const' somewhere. But better post
the error message, even if it seems gibberish to you it may actually
contain information for others.


DSF

unread,
Jan 26, 2015, 4:00:38 PM1/26/15
to
On Mon, 26 Jan 2015 08:33:06 +1300, Ian Collins <ian-...@hotmail.com>
wrote:

>DSF wrote:
>> Hello, group!
>>
>> I have a template class that requires "==" to be overloaded in any
>> class that uses it. If the class doesn't overload "==", I get the
**>> compile time message "Illegal structure operation" on the "=="
>> comparison line. This is the error I am receiving. I have gone
>> through the entire project and every class is never used with the
>> template class or has "==" overloaded.
>
>You need to provide more detail - example code that fails to compile and
>the exact error message.

** No offense, but I gave you the exact error message.

Below is a mock-up of the problem.

For the pedants out there, yes I know include files aren't supposed
to have an extension. Dumbest idea! If you don't think so, try
searching an entire drive for all header files. Also, I prefer printf
over <<, so shoot me! :o)

As is, the code below will produce the "Illegal structure operation"
on the line:
return object == obj;

Remark out #define NOCOMPILE and it will compile and run.

This is because the first declaration for object Foo does not
overload operator ==, while the second does.

In my original source code, the TU that generates this error does
not even use the template represented by "Tester". All other TUs
compile error-free.

#include <stdio.h>

#define NOCOMPILE

#ifdef NOCOMPILE
class Foo
{
public:
Foo(int n) : num(n){};

private:
int num;
};

#else

class Foo
{
public:
Foo(int n) : num(n){};
friend bool operator==(const Foo& f1, const Foo& f2);

private:
int num;
};

inline bool operator==(const Foo& f1, const Foo& f2)
{
return f1.num == f2.num;
}
#endif


template <class T> class Tester
{
public:
Tester(const T& obj) : object(obj){};
bool CompareObject(const T& obj)
{
return object == obj; // <-HERE
}

private:
T object;
};


int main()
{
Foo fo1(12);
Foo fo2(14);

Tester<Foo> testfoo(fo1);

bool result = testfoo.CompareObject(fo2);
printf("fo1 %s equal fo2\n", result ? "does" : "does not");
return 0;

DSF

unread,
Jan 26, 2015, 4:10:17 PM1/26/15
to
The entire message, as stated before, is: "Illegal structure
operation". See my answer to Ian Collins for more.

>What compiler are you using?

Borland C/C++ 5.01A

Yes, I know.

>Tobi

DSF

unread,
Jan 26, 2015, 4:12:17 PM1/26/15
to
I did post the entire error message. See my reply to Ian Collins
for details.

Ian Collins

unread,
Jan 26, 2015, 4:24:42 PM1/26/15
to
DSF wrote:
> On Mon, 26 Jan 2015 08:33:06 +1300, Ian Collins <ian-...@hotmail.com>
> wrote:
>
>> DSF wrote:
>>> Hello, group!
>>>
>>> I have a template class that requires "==" to be overloaded in any
>>> class that uses it. If the class doesn't overload "==", I get the
> **>> compile time message "Illegal structure operation" on the "=="
>>> comparison line. This is the error I am receiving. I have gone
>>> through the entire project and every class is never used with the
>>> template class or has "==" overloaded.
>>
>> You need to provide more detail - example code that fails to compile and
>> the exact error message.
>
> ** No offense, but I gave you the exact error message.

We probably didn't realise that due to the error message being so unhelpful!

> Below is a mock-up of the problem.
>
> For the pedants out there, yes I know include files aren't supposed
> to have an extension. Dumbest idea! If you don't think so, try
> searching an entire drive for all header files. Also, I prefer printf
> over <<, so shoot me! :o)
>
> As is, the code below will produce the "Illegal structure operation"
> on the line:
> return object == obj;
>
> Remark out #define NOCOMPILE and it will compile and run.
>
> This is because the first declaration for object Foo does not
> overload operator ==, while the second does.

So that's your problem, isn't it?

You can't compare without a comparison operator...

--
Ian Collins

Christian Gollwitzer

unread,
Jan 26, 2015, 4:31:07 PM1/26/15
to
Am 26.01.15 um 22:00 schrieb DSF:
> #include <stdio.h>
> [...]

Even if you use Borland C++ for production work, it is ALWAYS a good
idea to install another compiler to track down such errors. Here is what
I get from clang:

Apfelkiste:Tests chris$ clang nocomp.cpp
nocomp.cpp:40:17: error: invalid operands to binary expression ('Foo'
and 'const Foo')
return object == obj; // <-HERE
~~~~~~ ^ ~~~
nocomp.cpp:55:24: note: in instantiation of member function
'Tester<Foo>::CompareObject' requested here
bool result = testfoo.CompareObject(fo2);
^
1 error generated.
Apfelkiste:Tests chris$

clang and gcc are both free to download and work on all modern platforms.

Christian

Christian Gollwitzer

unread,
Jan 26, 2015, 4:32:41 PM1/26/15
to
Am 26.01.15 um 22:30 schrieb Christian Gollwitzer:
> Am 26.01.15 um 22:00 schrieb DSF:
>> #include <stdio.h>
>> [...]
>
> Even if you use Borland C++ for production work, it is ALWAYS a good
> idea to install another compiler to track down such errors. Here is what
> I get from clang:

And here comes gcc:

Apfelkiste:Tests chris$ g++-mp-4.6 nocomp.cpp
nocomp.cpp: In member function 'bool Tester<T>::CompareObject(const T&)
[with T = Foo]':
nocomp.cpp:55:41: instantiated from here
nocomp.cpp:40:20: error: no match for 'operator==' in
'((Tester<Foo>*)this)->Tester<Foo>::object == obj'
Apfelkiste:Tests chris$

Both error messages are way more helpful than the illegal something that
your compiler reports.


Christian

Paavo Helde

unread,
Jan 26, 2015, 4:36:47 PM1/26/15
to
DSF <nota...@address.here> wrote in
news:9abdcahuelij2c1mp...@4ax.com:

>>
> I did post the entire error message. See my reply to Ian Collins
> for details.

For the record, the error message was:

> "Illegal structure operation"

It is nice to see so compact error message from template code :-) And
it's also nice that class Foo is called a "structure" :-).

For comparison, an error message from a compiler released in this century
is:


40 : error: invalid operands to binary expression ('Foo' and 'const Foo')

return object == obj; // <-HERE

~~~~~~ ^ ~~~

55 : note: in instantiation of member function 'Tester::CompareObject'
requested here

bool result = testfoo.CompareObject(fo2);

^

1 error generated.

Compilation failed


Well, the meaning is the same: you cannot compare Foo objects with '=='
if you have not defined that operator.

Cheers
Paavo

Tobias Müller

unread,
Jan 26, 2015, 4:57:50 PM1/26/15
to
DSF <nota...@address.here> wrote:
> On Mon, 26 Jan 2015 17:36:51 +0000 (UTC), Tobias Müller
> <tro...@bluewin.ch> wrote:
>> [...]
>> Usually the compiler error message tells you that and more:
>> - the full template type
>> - all template parameters
>> - point of instatiation
>> etc
>
> The entire message, as stated before, is: "Illegal structure
> operation". See my answer to Ian Collins for more.

Well to be precise what I wanted to say was:
"All compilers that I know give you some meaningful information. What
compiler could you possibly be using that doesn't give you that?"

>> What compiler are you using?
>
> Borland C/C++ 5.01A
>
> Yes, I know.

Do you realize that this is almost 20 years old?

Tobi

DSF

unread,
Jan 26, 2015, 11:41:28 PM1/26/15
to
On Mon, 26 Jan 2015 21:57:06 +0000 (UTC), Tobias Müller
LOL! LOL! LOL! LOL!

No offense meant, but thanks for the laugh! I have broken or at
least severely bent causality by answering your question before you
asked it, i.e. effect -> cause.

DSF

unread,
Jan 27, 2015, 3:22:06 AM1/27/15
to
On Sun, 25 Jan 2015 14:28:05 -0500, DSF <nota...@address.here>
wrote:

>Hello, group!

I should mention in the very slight defense off my 25-year-old
compiler that it does also highlight the line with the error and list
its approximate location before the error.
! FAList.h(530,1):Illegal structure operation

So I know what template it is in and I can translate the error to
"The == operator is not a standard operator that can be used with
structures (classes)." Meaning I have an instance somewhere of
FAList<some_class> foo, where some_class has not overloaded ==. My
problem being the message doesn't identify "some_class".

I can't afford the time right now to learn my way around a new
compiler. Not to mention all the source I'll have to recompile. And
even though I have all warnings and errors enabled in my current
moldy-oldie, I'm sure there will be *many* lines of code indigestible
to the new compiler without tweaking.

In fact, I have a compiler ready for installation in a virtual
machine, but I need the use of the utility I'm writing (the one with
this error) to have the disk space to set up the virtual machine.

I've searched every file in the project and associated libraries for
FAList< and every instance the class inside the angle brackets has an
overloaded ==. I did encounter something unusual. I'll summarize it:

class Foo
{
public:
...etc...
friend bool operator==(const Foo& foo1, const Foo& foo2);
...
};

inline bool operator==(const Foo& foo1, const Foo foo2)
{do comparison};

Note the missing ampersand on the second Foo of the inline line.
Shouldn't this be an error? The TU compiled with 0 errors and 0
warnings. BTW, adding the ampersand did not fix the main problem.

Thanks for all your responses,

Rosario193

unread,
Jan 27, 2015, 3:23:37 AM1/27/15
to
On Mon, 26 Jan 2015 16:00:28 -0500, DSF wrote:
...
> As is, the code below will produce the "Illegal structure operation"
>on the line:
> return object == obj;
>
this compile and run here...
#include <stdio.h>

class Foo
{public:
Foo(int n): num(n){;}
Foo(Foo& a){if(&a!=this) num=a.num;}
friend int operator==(Foo& f1, Foo& f2);

int num;
};

int operator==(Foo& f1, Foo& f2){return f1.num==f2.num;}

template<class T>class Tester
{public:
int CompareObject(T& obj){return object==obj;}
Tester(T& obj):object(obj){;}

T object;
};


int main(void)
{Foo fo1(12);
Foo fo2(12);
Tester<Foo> testfoo(fo1);
int result=testfoo.CompareObject(fo2);

Rosario193

unread,
Jan 27, 2015, 4:05:12 AM1/27/15
to
On Tue, 27 Jan 2015 09:23:33 +0100, Rosario193 wrote:

>this compile and run here...
>#include <stdio.h>
>
>class Foo
>{public:
> Foo(int n): num(n){;}
> Foo(Foo& a){if(&a!=this) num=a.num;}
> friend int operator==(Foo& f1, Foo& f2);
>
> int num;
>};
>
>int operator==(Foo& f1, Foo& f2){return f1.num==f2.num;}
>
>template<class T>class Tester
>{public:
> int CompareObject(T& obj){return object==obj;}
> Tester(T& obj):object(obj){;}
>
> T object;
>};
>
>
>int main(void)
>{Foo fo1(12);
> Foo fo2(12);
> Tester<Foo> testfoo(fo1);
> int result=testfoo.CompareObject(fo2);
>
> printf("fo1 %s equal fo2\n", result ? "does" : "does not");
> return 0;
>}

_TEXT segment dword public use32 'CODE'
@$beql$qr3Foot1 segment virtual
@@$beql$qr3Foot1 proc near
?live16385@0:
;
; int operator==(Foo& f1, Foo& f2){return f1.num==f2.num;}
;
push ebp
mov ebp,esp
@1:
mov eax,dword ptr [ebp+8]
mov edx,dword ptr [eax]
mov ecx,dword ptr [ebp+12]
cmp edx,dword ptr [ecx]
sete al
and eax,1
@3:
@2:
pop ebp
ret
@@$beql$qr3Foot1 endp
@$beql$qr3Foot1 ends
_TEXT ends
_TEXT segment dword public use32 'CODE'
_main segment virtual
@_main proc near
?live16386@0:
;
; int main(void)
;
push ebp
mov ebp,esp
add esp,-12
;
; {Foo fo1(12);
;
@4:
mov dword ptr [ebp-4],12
;
; Foo fo2(12);
;
mov dword ptr [ebp-8],12
;
; Tester<Foo> testfoo(fo1);
;
lea eax,dword ptr [ebp-4]
lea edx,dword ptr [ebp-12]
cmp eax,edx
je short @5
mov ecx,dword ptr [ebp-4]
mov dword ptr [ebp-12],ecx

here appear that is called
"Foo(Foo& a){if(&a!=this) num=a.num;}"
inline

;
; int result=testfoo.CompareObject(fo2);
;
@5:
@6:
lea eax,dword ptr [ebp-8]
push eax
lea edx,dword ptr [ebp-12]
push edx
call @@$beql$qr3Foot1
add esp,8

here it call the right function
int operator==(Foo& f1, Foo& f2){return f1.num==f2.num;}

and printf result:

;
;
; printf("fo1 %s equal fo2\n", result ? "does" : "does not");
;
?live16386@80: ; EAX = result
test eax,eax
je short @7
mov ecx,offset s@+18
jmp short @8
@7:
mov ecx,offset s@+23
@8:
push ecx
push offset s@
call @_printf
add esp,8
;
; return 0;
;
?live16386@96: ;
xor eax,eax
;
; }
;
@10:
@9:
mov esp,ebp
pop ebp
ret
@_main endp
_main ends

Bo Persson

unread,
Jan 27, 2015, 6:18:14 AM1/27/15
to
On 2015-01-27 09:22, DSF wrote:

> I've searched every file in the project and associated libraries for
> FAList< and every instance the class inside the angle brackets has an
> overloaded ==. I did encounter something unusual. I'll summarize it:
>
> class Foo
> {
> public:
> ...etc...
> friend bool operator==(const Foo& foo1, const Foo& foo2);
> ...
> };
>
> inline bool operator==(const Foo& foo1, const Foo foo2)
> {do comparison};
>
> Note the missing ampersand on the second Foo of the inline line.
> Shouldn't this be an error? The TU compiled with 0 errors and 0
> warnings.

That's a different operator that doesn't match the friend declaration.
It will compare foo1 against a copy of foo2, but is perfectly legal.


> BTW, adding the ampersand did not fix the main problem.
>

Too bad.


Bo Persson

Louis Krupp

unread,
Jan 27, 2015, 9:23:36 AM1/27/15
to
On Mon, 26 Jan 2015 16:00:28 -0500, DSF <nota...@address.here>
wrote:
Is it possible that this has nothing to do with templates? Compiling
this code with -c seems to reproduce the problem:

===
class Foo
{
public:
Foo() : num(0){};

int num;
};

#if 0
bool operator==(const Foo& f1, const Foo& f2)
{
return f1.num == f2.num;
}
#endif

void s()
{
Foo f1, f2;

if (f1 == f2);
}
===

Change #if 0 to #if 1, and it compiles.

The problem seems to match this:

http://stackoverflow.com/questions/5740310/no-operator-found-while-comparing-structs-in-c

Louis

Paavo Helde

unread,
Jan 27, 2015, 1:59:26 PM1/27/15
to
DSF <nota...@address.here> wrote in
news:0q6eca5121metb387...@4ax.com:

>
> I should mention in the very slight defense off my 25-year-old
> compiler that it does also highlight the line with the error and list
> its approximate location before the error.
> ! FAList.h(530,1):Illegal structure operation
>
> So I know what template it is in and I can translate the error to
> "The == operator is not a standard operator that can be used with
> structures (classes)." Meaning I have an instance somewhere of
> FAList<some_class> foo, where some_class has not overloaded ==. My
> problem being the message doesn't identify "some_class".
>
> I can't afford the time right now to learn my way around a new
> compiler. Not to mention all the source I'll have to recompile. And
> even though I have all warnings and errors enabled in my current
> moldy-oldie, I'm sure there will be *many* lines of code indigestible
> to the new compiler without tweaking.

Too bad. In this case you can take the failing TU and start commenting
out pieces of it with #if 0 ... #endif. First comment out the whole cpp
file except your header include line. According to your description it
should now compile as other TU-s including the header are compiling. Then
comment out only bottom half of the file, etc. With this bisection method
you should converge to the failing line pretty soon.

hth
Paavo

DSF

unread,
Feb 5, 2015, 4:00:25 AM2/5/15
to
On Sun, 25 Jan 2015 14:28:05 -0500, DSF <nota...@address.here>
wrote:

Hello, group!

> I have a template class that requires "==" to be overloaded in any
>class that uses it. If the class doesn't overload "==", I get the
>compile time message "Illegal structure operation" on the "=="
>comparison line. This is the error I am receiving. I have gone
>through the entire project and every class is never used with the
>template class or has "==" overloaded.
>
> If it were a runtime error, I could track down the class involved.
>But as it stands, I'm stuck! Any ideas on how to track down this
>error?
>

Problem found and solved! In retrospect, there was an "if it was a
snake, it would've bitten you" clue in my post "Linker errors
involving template". It only became obvious since I found this error.

How did I find it? Through many sleepless nights and blurry-eyed
days. :o)

Until I got the idea about 45 minutes ago to use the command line
version of the compiler and see if it gave a more detailed answer. It
did:

Error e:\library\include\CPP/FAList.h 530: Illegal structure operation
in function FAList<HashIndex>::Find(const HashIndex &) const

Finally! A class to go with FAList! (The same class referred to in
"Linker errors involving template".)

The problem? Almost too embarrassing to relate...almost.

HashIndex has six members:
bool firsthash;
int64 hash;
FString firstname;
FString originalname;
FAList<AlternateNames> altnames;
uint duplicates;

It overloads all of the comparison operators through friends. The
comparisons are all based on the member "hash". For some now unknown
reason, that was what I concentrated on. So I had the following code:
(Only one comparison operator shown for brevity, but they were all
this way...Sigh!)

HashIndex
{
public:
...
friend bool operator == (int64 h1, int64 h2);
};
inline bool operator==(int64 h1, int64 h2)
{return Cmp64To64(h1, h2) == 0);}

It finally occurred to me half an hour ago that you're supposed to
pass const references of the class to operator ==, not the member you
want to test! D'Oh!

So it became:
HashIndex
{
public:
...
friend bool operator==(const HashIndex& h1, const HashIndex& h2);
};
inline bool operator==(const HashIndex& h1, const HashIndex& h2)
{return Cmp64To64(h1.hash, h2.hash) == 0;}

And all is peaceful again in Whoville!

Martijn Lievaart

unread,
Feb 8, 2015, 3:26:00 PM2/8/15
to
On Thu, 05 Feb 2015 04:00:03 -0500, DSF wrote:

> Problem found and solved! In retrospect, there was an "if it was a
> snake, it would've bitten you" clue in my post "Linker errors involving
> template". It only became obvious since I found this error.
>
> How did I find it? Through many sleepless nights and blurry-eyed
> days. :o)

Thanks for the extensive followup!

M4
0 new messages