473,385 Members | 1,720 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

STL list code fires assertion in VC++ 2005, but not in VC++ 2003.

I'm getting an assertion fire from a list iterator being checked
against NULL. This did not occur in VC++ 2003 (v7.1). Are there
changes that have been made to the STL between these versions that I
should know about? Any resources I should check into?

thanks,
Jason

Jun 28 '07 #1
27 2731
Jason Doucette wrote:
I'm getting an assertion fire from a list iterator being checked
against NULL.
Why are you doing that?
This did not occur in VC++ 2003 (v7.1). Are there
changes that have been made to the STL between these versions that I
should know about?
Probably. Actually, very likely.
Any resources I should check into?
FAQ 5.8

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 28 '07 #2
I'm getting an assertion fire from a list iterator being checked
against NULL.

Why are you doing that?
Because I have a function that reports whether or not an element is in
the list. If it is, it returns an iterator to that element. If it's
not, then it returns NULL.

Is this bad? It worked fine in VC++ 2003. But, the internals of the
STL list class doesn't seem to like it, anymore.
This did not occur in VC++ 2003 (v7.1). Are there
changes that have been made to the STL between these versions that I
should know about?

Probably. Actually, very likely.
I recall reading something a long time ago that they had made some
changes. I can't seem to find a decent resource on this, though.
Any resources I should check into?

FAQ 5.8
Of what manual? The C++ Standard? I don't think it's publicly
available.

Thanks, Victor.

Jason

Jun 28 '07 #3
FAQ 5.8

Sorry, you mean the newsgroup FAQ, obviously, duh. I had forgotten
which newsgroup I was replying to.

cheers,
Jason

Jun 28 '07 #4
Sorry, you mean the newsgroup FAQ, obviously, duh. I had forgotten
which newsgroup I was replying to.
....which is parashift.com's C++ FAQ Lite, which is not a FAQ just for
this group.

5.8 is about posting non-working code questions:
http://www.parashift.com/c++-faq-lit...t.html#faq-5.8
Is this what you mean?

If so, I am not asking anyone to fix my code. I'm looking for a
resource (that I can research myself) about what changes were made to
the STL implementation from VC++ 2003 to VC++ 2005, so I can determine
what I'm now doing wrong.

Thanks,
Jason

Jun 28 '07 #5
Jason Doucette <jd*******@gmail.comwrote:
I'm getting an assertion fire from a list iterator being checked
against NULL. This did not occur in VC++ 2003 (v7.1). Are there
changes that have been made to the STL between these versions that I
should know about? Any resources I should check into?
MS added "checked iterators" in VS 2005. See:
http://msdn2.microsoft.com/en-us/lib...65(VS.80).aspx

If you need more info on them, you should probably consult a Visual
Studio group.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Jun 28 '07 #6
On 2007-06-28 21:30, Jason Doucette wrote:
I'm getting an assertion fire from a list iterator being checked
against NULL. This did not occur in VC++ 2003 (v7.1). Are there
changes that have been made to the STL between these versions that I
should know about? Any resources I should check into?
No, the STL is probably the same. But the implementation in VS might
have changed. Consider yourself lucky this probably means you have
uncovered a hidden bug in your code. By the way, what do you mean with
the iterator being checked against NULL? Who did the check?

--
Erik Wikström
Jun 28 '07 #7
Jason Doucette <jd*******@gmail.comwrote:
I'm getting an assertion fire from a list iterator being checked
against NULL.

Why are you doing that?

Because I have a function that reports whether or not an element is in
the list. If it is, it returns an iterator to that element. If it's
not, then it returns NULL.
Oh, I misinterpreted your original post. For containers, usually
functions that work with them are passed a start iterator
(container.begin()) and a one-past-the-last iterator (container.end()).
If the element isn't found, then the one-past-the-last iterator is
returned.
Is this bad? It worked fine in VC++ 2003. But, the internals of the
STL list class doesn't seem to like it, anymore.
Pointers are valid iterators, so my guess is that in VC++ 2003, the
iterators were implemented as pointers, so the comparison with NULL
worked. But then, in 2005, they added the checked iterators, which is
probably a whole class instead of a simple pointer, so the comparison
with NULL is no longer valid.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Jun 28 '07 #8
MS added "checked iterators" in VS 2005. See:http://msdn2.microsoft.com/en-us/lib...65(VS.80).aspx

Marcus, this link lead me to the page I was looking for:

Breaking Changes in the Standard C++ Library
http://msdn2.microsoft.com/en-us/lib...46(VS.80).aspx

Specifically, this section:

"Debug Iterators
Applications built with a debug version of the C-Runtime Library and
which use iterators incorrectly might begin to see asserts at runtime.
To disable these asserts, you must define _HAS_ITERATOR_DEBUGGING to
0. For more information, see Debug Iterator Support."

So, I have been using iterators incorrectly this entire time. Perhaps
it has to do with me setting them to NULL, or not initializing them
explicitly to a value that makes sense. I am not sure, I'll have to
research this.

Thanks for your help,
Jason

Jun 28 '07 #9
Jason Doucette wrote:
>Sorry, you mean the newsgroup FAQ, obviously, duh. I had forgotten
which newsgroup I was replying to.

...which is parashift.com's C++ FAQ Lite, which is not a FAQ just for
this group.

5.8 is about posting non-working code questions:
http://www.parashift.com/c++-faq-lit...t.html#faq-5.8
Is this what you mean?

If so, I am not asking anyone to fix my code. I'm looking for a
resource (that I can research myself) about what changes were made to
the STL implementation from VC++ 2003 to VC++ 2005, so I can determine
what I'm now doing wrong.

Thanks,
Jason
Victor was almost certainly trying to hint that you should post some
code. Without seeing code that demonstrates the error, the best we can
do is guess.

From the rest of this thread, it appears to me that you are under the
impression that iterators are pointers, which is not (necessarily) true.
Setting an iterator to NULL, for example, doesn't make any sense. You
should treat an iterator as an opaque object that can only be used in
the expressions guaranteed by the standard. If you don't have a copy of
the standard, the following is reasonably close to correct:
http://www.sgi.com/tech/stl/table_of_contents.html

The equivalent of a NULL pointer for iterators is the past-the-end
iterator (what you get from container.end()). The correct way to do
what you described elsewhere in the thread would look something like this:

template <typename T>
typename std::list<T>::iterator some_algorithm(
const std::list<T& lst, const T & value)
{
// Do whatever and return an iterator.

// Not found, return the past the end iterator.
return lst.end();
}

void some_function()
{
std::list<intlst;
// ...

std::list<int>::iterator i = some_algorithm(lst, 42);
if (i == lst.end())
{
// Handle not found case.
}
}

--
Alan Johnson
Jun 28 '07 #10
Jason Doucette <jd*******@gmail.comwrote:
So, I have been using iterators incorrectly this entire time. Perhaps
it has to do with me setting them to NULL, or not initializing them
explicitly to a value that makes sense.
Yes, I think this is the case. See Alan Johnson's post or my other post
for suggestions on how you should handle the not-found case instead of
trying to return NULL.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Jun 28 '07 #11
No, the STL is probably the same. But the implementation in VS might
have changed. Consider yourself lucky this probably means you have
uncovered a hidden bug in your code. By the way, what do you mean with
the iterator being checked against NULL? Who did the check?
I have a function that checks a list for some data, by iterating
through it. If it finds the element, it returns the iterator to it.
If not, it returns NULL. The caller of this function checks the
return value (an iterator) to see if it's NULL or not. (Kind of like
a pointer, it either points to something, or NULL...)

std::list<myStructmyList;
std::list<myStruct>::iterator myIterator;

for (myIterator = myList.begin(); myIterator != myList.end();
myIterator++)
{
if (myIterator != NULL) <----- BANG!
}

thanks,
Jason

Jun 28 '07 #12
Oh, I misinterpreted your original post. For containers, usually
functions that work with them are passed a start iterator
(container.begin()) and a one-past-the-last iterator (container.end()).
If the element isn't found, then the one-past-the-last iterator is
returned.
Oh... so I should probably use this concept, as well. To be
consistent. In fact, it may be the only correct way to do it.

I should note that the assertion fires when the iterator is NOT NULL,
but is a legit element. It appears that it cannot be compared to
NULL. It used to be ok to treat it like any old pointer (perhaps
because VC++ 7.1 didn't care), but now it seems this is not ok (which
was likely always the case, for STL).
Pointers are valid iterators, so my guess is that in VC++ 2003, the
iterators were implemented as pointers, so the comparison with NULL
worked. But then, in 2005, they added the checked iterators, which is
probably a whole class instead of a simple pointer, so the comparison
with NULL is no longer valid.
Right. The checked iterators do check that they are in range. But,
my issue isn't an out-of-range one (although, eventually, it will be
when the function that does a search fails, and wants to return
NULL). My current issue is that an iterator that points to a real
element cannot be compared to NULL. Your diagnosis sounds correct.

Thanks, Marcus
Jason

Jun 28 '07 #13
Victor was almost certainly trying to hint that you should post some
code. Without seeing code that demonstrates the error, the best we can
do is guess.
Right. I didn't want people to solve my code problem. I just wanted
a resource section so I could solve it myself. But, you guys have
done an amazing job, nonetheless.
From the rest of this thread, it appears to me that you are under the
impression that iterators are pointers, which is not (necessarily) true.
Setting an iterator to NULL, for example, doesn't make any sense. You
should treat an iterator as an opaque object that can only be used in
the expressions guaranteed by the standard.
I think this is exactly my problem.
If you don't have a copy of
the standard, the following is reasonably close to correct:
http://www.sgi.com/tech/stl/table_of_contents.html
Thank you.
The equivalent of a NULL pointer for iterators is the past-the-end
iterator (what you get from container.end()). The correct way to do
what you described elsewhere in the thread would look something like this:

template <typename T>
typename std::list<T>::iterator some_algorithm(
const std::list<T& lst, const T & value)
{
// Do whatever and return an iterator.

// Not found, return the past the end iterator.
return lst.end();
}

void some_function()
{
std::list<intlst;
// ...

std::list<int>::iterator i = some_algorithm(lst, 42);
if (i == lst.end())
{
// Handle not found case.
}
}
Right, thanks a lot, Alan! This is exactly what I will need to
change.

Jason

Jun 28 '07 #14
Jason Doucette wrote:
>No, the STL is probably the same. But the implementation in VS might
have changed. Consider yourself lucky this probably means you have
uncovered a hidden bug in your code. By the way, what do you mean
with the iterator being checked against NULL? Who did the check?

I have a function that checks a list for some data, by iterating
through it. If it finds the element, it returns the iterator to it.
If not, it returns NULL. The caller of this function checks the
return value (an iterator) to see if it's NULL or not. (Kind of like
a pointer, it either points to something, or NULL...)

std::list<myStructmyList;
std::list<myStruct>::iterator myIterator;

for (myIterator = myList.begin(); myIterator != myList.end();
myIterator++)
{
if (myIterator != NULL) <----- BANG!
}
This code isn't even remotely close to the real code, Jason. There
is no "function", there is no "caller"...

Does the caller have access to the list? If he does, returning the
'end()' is much better than relying on the iterator's comparability
with NULL. It he does not, why does it have to be an iterator? Make
your function return a pointer, to the contained element if success
and NULL if not.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jun 28 '07 #15
This code isn't even remotely close to the real code, Jason. There
is no "function", there is no "caller"...
Sorry, I determined the function / caller wasn't the issue. It was
the iterator being compared to NULL, when it was set to being
something legitimate (between myList.begin() and myList.end()). So,
instead of making the problem more complex, I shortened it down as
much as I could, to remove all things that were irrelevant.

I believe the issue is resolved... I've been using iterators like
pointers, which is no longer safe since the switch from VC++7.1 to VC+
+8.0, as mentioned a few times elsewhere. So, I'll rework my code as
you and others have suggested, and I am confident it will work. I'll
post back and let you know.
Does the caller have access to the list? If he does, returning the
'end()' is much better than relying on the iterator's comparability
with NULL. It he does not, why does it have to be an iterator? Make
your function return a pointer, to the contained element if success
and NULL if not.
Yes, the caller does have access to the list, so returning end() is an
option, and sounds like something much better to use. I didn't know
it was standard practice to use this for something "out of range". (I
guess pointers / NULL just seemed intuitive.)

The caller makes use of the information within the element it gets (if
not NULL), and then deletes it from the list. So, having the iterator
to this element is ideal, since deleting it via erase() is very easy,
as it takes in an iterator to the element you want erased.

Thanks for your time,
Jason

Jun 28 '07 #16
On 28 Jun, 22:53, Jason Doucette <jdouce...@gmail.comwrote:
Does the caller have access to the list? If he does, returning the
'end()' is much better than relying on the iterator's comparability
with NULL. It he does not, why does it have to be an iterator? Make
your function return a pointer, to the contained element if success
and NULL if not.

Yes, the caller does have access to the list, so returning end() is an
option, and sounds like something much better to use. I didn't know
it was standard practice to use this for something "out of range". (I
guess pointers / NULL just seemed intuitive.)

The caller makes use of the information within the element it gets (if
not NULL), and then deletes it from the list. So, having the iterator
to this element is ideal, since deleting it via erase() is very easy,
as it takes in an iterator to the element you want erased.
It is ideal - and that's not by happy coincidence, it's by design. Now
you've discovered the idomatic way to use iterators, have a look at
how the standard library algoriths fit together with containers and
iterators. For example, it sounds like there could be a way to replace
your function with a single call to std::find. Might or might not be
easy - and if it is, it might or might not be worth it if you've got
your function already written and tested, but it will be useful
knowledge for next time.

Gavin Deane

Jun 28 '07 #17
Jason Doucette wrote:
My current issue is that an iterator that points to a real
element cannot be compared to NULL.
Technically, that's always been the case.
Jun 28 '07 #18
On Jun 28, 11:53 pm, Jason Doucette <jdouce...@gmail.comwrote:

[...]
Does the caller have access to the list? If he does, returning the
'end()' is much better than relying on the iterator's comparability
with NULL. It he does not, why does it have to be an iterator? Make
your function return a pointer, to the contained element if success
and NULL if not.
Yes, the caller does have access to the list, so returning end() is an
option, and sounds like something much better to use. I didn't know
it was standard practice to use this for something "out of range". (I
guess pointers / NULL just seemed intuitive.)
It's the usual solution when the user is aware of the list.
Another, more general solution is to use Barton and Nackman's
Fallible as a return value.
The caller makes use of the information within the element it gets (if
not NULL), and then deletes it from the list. So, having the iterator
to this element is ideal, since deleting it via erase() is very easy,
as it takes in an iterator to the element you want erased.
This sounds like something Fallible was designed for. The
client has no need to "know" anything about the list.

--
James Kanze (GABI Software) email:ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 29 '07 #19
It is ideal - and that's not by happy coincidence, it's by design.

Yes.
Now
you've discovered the idomatic way to use iterators, have a look at
how the standard library algoriths fit together with containers and
iterators. For example, it sounds like there could be a way to replace
your function with a single call to std::find. Might or might not be
easy - and if it is, it might or might not be worth it if you've got
your function already written and tested, but it will be useful
knowledge for next time.
I didn't use std::find, since I had to search for a match of a struct
field, in a list of such structs. But, I could have defined the
equality operator == for this struct, and used std::find. The actual
search code is so small (just a simple for loop), that it's no big
deal, really. But, I'll keep this in mind for the next time.

Jason
Jun 29 '07 #20
element cannot be compared to NULL.
>
Technically, that's always been the case.
Yes, I am aware of that. VC++ 7.1's implementation merely allowed me
to use them as pointers. I could just turn off VC++ 8.0's debug
warnings, but I'd rather code correctly, and leave all warnings on.

Jason
Jun 29 '07 #21
Yes, the caller does have access to the list, so returning end() is an
option, and sounds like something much better to use. I didn't know
it was standard practice to use this for something "out of range". (I
guess pointers / NULL just seemed intuitive.)

It's the usual solution when the user is aware of the list.
Another, more general solution is to use Barton and Nackman's
Fallible as a return value.
The caller makes use of the information within the element it gets (if
not NULL), and then deletes it from the list. So, having the iterator
to this element is ideal, since deleting it via erase() is very easy,
as it takes in an iterator to the element you want erased.

This sounds like something Fallible was designed for. The
client has no need to "know" anything about the list.
James, can you elaborate on Barton and Nackman's Fallible? I will
research it right now, since it sounds like what I need.

An issue that remains is that I have a pointer to the list. If the
pointer is NULL, the list doesn't even exist. Thus, I cannot return
myList.end() in such a case. (Incidentally, the reason I use a
pointer is so I can check the list's constructor for errors -- I am
very picky about error checking).

Thanks,
Jason

Jun 29 '07 #22
Jason Doucette <jd*******@gmail.comwrote:
An issue that remains is that I have a pointer to the list. If the
pointer is NULL, the list doesn't even exist. Thus, I cannot return
myList.end() in such a case. (Incidentally, the reason I use a
pointer is so I can check the list's constructor for errors -- I am
very picky about error checking).
The common idiom for constructor errors is to have the constructor throw
an exception.

--
Marcus Kwok
Replace 'invalid' with 'net' to reply
Jun 29 '07 #23
The common idiom for constructor errors is to have the constructor throw
an exception.
Yes. A lot of code have STL containers as globals, seemingly
oblivious to the fact that their constructors are being run (even just
to create an empty list) without any code to catch that exception.

So, I use use a pointer to the list, and make that global, instead.
Then, the creation of the list can exist in code that catches any
constructor exceptions.

Jason

Jun 29 '07 #24
Jason Doucette <jd*******@gmail.comwrote in news:1183149322.923752.155870
@k79g2000hse.googlegroups.com:
>The common idiom for constructor errors is to have the constructor throw
an exception.

Yes. A lot of code have STL containers as globals, seemingly
oblivious to the fact that their constructors are being run (even just
to create an empty list) without any code to catch that exception.

So, I use use a pointer to the list, and make that global, instead.
Then, the creation of the list can exist in code that catches any
constructor exceptions.
Out of curiosity... what exception do you expect your list's constructor to
throw? (Assuming default constructor for the list)
Jun 29 '07 #25
Andre Kostur wrote:
Jason Doucette <jd*******@gmail.comwrote in
news:1183149322.923752.155870 @k79g2000hse.googlegroups.com:
>>The common idiom for constructor errors is to have the constructor throw
an exception.

Yes. A lot of code have STL containers as globals, seemingly
oblivious to the fact that their constructors are being run (even just
to create an empty list) without any code to catch that exception.

So, I use use a pointer to the list, and make that global, instead.
Then, the creation of the list can exist in code that catches any
constructor exceptions.

Out of curiosity... what exception do you expect your list's constructor
to throw? (Assuming default constructor for the list)
It could throw a bad_alloc. If the list uses an extra node as the past_end
node, the pointer to which is returned by end(), then there could be an
allocation even for the empty list.
Best

Kai-Uwe Bux
Jun 29 '07 #26
On Jun 29, 9:49 pm, Jason Doucette <jdouce...@gmail.comwrote:
James, can you elaborate on Barton and Nackman's Fallible? I will
research it right now, since it sounds like what I need.
It's the "standard" solution anytime a function might not be
able to return a legitimate value. In its simplest form:

template< typename T >
class Fallible
{
public:
Fallible()
: myIsValid( false )
{}
Fallible( T const& value )
: myIsValid( true )
, myValue( value )
{}

bool isValid() const
{
return myIsValid ;
}

T const& value() const
{
assert( myIsValid ) ;
return myValue ;
}
private:
bool myIsValid ;
T myValue ;
} ;

For a version with all sorts of bells and whistles (and which
really goes beyond the concept of Fallible, and should probably
be several different classes), see the code at my site
(kanze.james.neuf.fr//code-en.html---subsystem Basic, component
Fallible). The one extension there that you probably do want is
the member function "elseDefaultTo()"; the rest is really
support for other uses.

--
James Kanze (Gabi Software) email: ja*********@gmail.com
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Jun 30 '07 #27
Out of curiosity... what exception do you expect your list's constructor to
throw? (Assuming default constructor for the list)
std::bad_alloc is the C++ standard for out of memory exceptions, which
is what the STL uses. Actually, it doesn't specifically use it, it's
just uses C++'s new internally, and this throws std::bad_alloc when it
fails, so the STL throws std::bad_alloc as a result.

Be cautious if you're using VC++ 6.0 or earlier since, without proper
attention, the default behaviour doesn't match the C++ standard; it
returns NULL.

Jason

Jul 1 '07 #28

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

0
by: Guohui He | last post by:
Hi All, I am trying to update our application from VC 6.0 to VC 7.1 (.NET 2003) as managed extension. Now the compilation seems to be fine and the release version works also. However, when I run...
11
by: Peter Oliphant | last post by:
Is there any plan to support templates with managed code in the (near) future? For instance, VS.NET 2005... : )
2
by: James S | last post by:
Hi I've been porting a project to .Net that has several segments of code that I would like to keep as native code in wrappers. I've been using VS2003 and VC++ to create mixed dlls that I then...
24
by: John Gabriel | last post by:
CreateDialogIndirect() fires my Radio button click function without the radio button having being clicked. I am using VC++ 2003.NET. I believe this is yet another Microsoft bug. Have checked dialog...
7
by: Mihajlo Cvetanović | last post by:
Hi all, I've been trying to find some info on Visual C++ 2005 Standard on Microsoft's site, but wasn't able to find any. There's only VC++ 2005 Express Edition, and Visual Studio 2005 Standard,...
5
by: techie | last post by:
Hi, I'm a VC++ programmer with around 5 years of experience using VC++6. My company have plans to migrate to VS 2005 in the future. I know C++/CLI is pretty new and there aren't too many books...
0
by: ashukasama | last post by:
Hello All, I have a dll created in c# visual studio 2005. i wanted to use this dll in vc++ project created in visual studio 2003. I am doing following steps for using the dll developed in 2005:...
2
by: Allen Maki | last post by:
I would be pleased if someone gives me a general idea; how I am going to do this. I am using visual C++ .NET 2003. I made a simple program using conventional C++ code. This program accepts...
1
by: David Bilsby | last post by:
All Apologies for cross posing this but I am not sure if this is a VC 8 STL bug or simply an invalid use of the iterator. I have a PCI card access class which basically abstracts a third party...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.