473,394 Members | 1,737 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,394 software developers and data experts.

GC! Why not ref count?

C++ is a great language. You can instantiate an object on
the stack, grab whatever resources you need, and free them
in the destructor. Object destructors are called in the
correct order (the reverse order), and are guaranteed to
be called when the object goes out of scope.

Unfortunately this is not so in C# (or Java) since you
cannot tell when the Garbage Collector will run. In C#
you can call Dispose (assuming it's implemented), but you
you still might have several references to a invalid
object floating around. Alternatively you can take
advantage of the using statement IF the class implements
IDispose, however this can become unwieldy if you need
several nested using blocks.

So why did the developers of C# (and Java) not reference
count objects? Surely it would have been a simple matter
to implement reference counting, and guarantee calling the
destructor when the last reference to an object was set to
null. The GC could still run periodically to clean up and
re-organize memory, but at least the resource cleanup
problem would have been solved.

What am I missing?

Thanks.
Nov 13 '05 #1
14 3947

"Ron James" <Ro*******@noapsm.rojacs.com> wrote in message
news:09****************************@phx.gbl...
C++ is a great language. You can instantiate an object on
the stack, grab whatever resources you need, and free them
in the destructor. Object destructors are called in the
correct order (the reverse order), and are guaranteed to
be called when the object goes out of scope.
That is only true of stack allocated objects. If you have heap allocated
objects then you are responsible for calling delete when done with the
object. This causes many problems... Memory leaks (no delete), calling
delete on invalid pointer (crash!), calling delete to an object that is
still needed (crash! or corruption). GC is popular because it frees the
programmer from the need to explicitly manage memory allocation.
Unfortunately this is not so in C# (or Java) since you
cannot tell when the Garbage Collector will run. In C#
you can call Dispose (assuming it's implemented), but you
you still might have several references to a invalid
object floating around. Alternatively you can take
advantage of the using statement IF the class implements
IDispose, however this can become unwieldy if you need
several nested using blocks.
You are not understanding the Dispose pattern. Dispose is only implemented
for classes that hold references to unmanaged resources - such as file
handles, window handles, database connections, socket handles, etc.) These
are limmited OS resources, that need to be returned as soon as possible. In
other words, you don't want to wait around for your finalize method to be
called for those resources to be released. Not only that, overriding
finalize has negative consequences for GC performance - because it requires
to GC's to completely destroy the object. So do get around that, MS has
provided a pattern based approach for dealing with these types of resources
via the IDisposable interface. Generally all necessary clean up is called
from both the finalize method as well as the Dispose method, with the added
step that System.GC.SuppressFinalize will be called in the Dispose method.
This lets you insure that unmanaged resources are cleaned up eventually -
even if a developer forgets to call Dispose, but rewards those that do
remember by removing the performance hit at GC time.
So why did the developers of C# (and Java) not reference
count objects? Surely it would have been a simple matter
to implement reference counting, and guarantee calling the
destructor when the last reference to an object was set to
null. The GC could still run periodically to clean up and
re-organize memory, but at least the resource cleanup
problem would have been solved.


Mostly because ref counting has several side affects.
1) Performance - generally reference counting schemes do not perform as well
as GC schemes as implemented in Java and .NET for the simple fact that they
have to be thread safe, which mean syncronization must be in place.

2) Referecne counting is easy to screw up. Often they are implmented using
methods that increment or decrement the Ref count and it is up to the
developer or the runtime to make sure these are called in a balanced manner.

3) Ref counting doesn't deal with object cycles well (aka circular
references). This is one of the major source of memory leaks in VB.CLASSIC.

The fact is that the style of GC used by C#/Java is much more effiecient and
less prone to error then reference counting...

Tom Shelton
Nov 13 '05 #2
Ron,

This was debated *a lot* in the early days of .NET. I suggest you read
this piece to get an idea of how the designers were thinking

http://discuss.develop.com/archives/...OTNET&P=R28572

Mattias

--
Mattias Sjögren [MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/
Please reply only to the newsgroup.
Nov 13 '05 #3
Check out some of the other OO languages which do handle large numbers
of objects and deal with memory management. You'll see they all
abandoned reference counting (mark and sweep) for two reasons

1 - It's very expensive. You have to visit every node every pass. At
least 2 times (mark and sweep pass) and once again if you're actually
using it. Slooooooowwwwwwwwwwwwwww.

2 - It doesn't exploit the situation. Most objects are either created
and blown away before they've drawn two breaths, or they stay around
like my old socks. Smalltalk and CLOS both headed for generation
scavenging in the early 90's, but I expect the fields become even more
abstruse at this point.
Nov 13 '05 #4
"Tom Shelton" <ts****@yahoo.com> wrote in message news:<#d**************@TK2MSFTNGP12.phx.gbl>...
"Ron James" <Ro*******@noapsm.rojacs.com> wrote in message
news:09****************************@phx.gbl... [snip]
Unfortunately this is not so in C# (or Java) since you
cannot tell when the Garbage Collector will run. In C#
you can call Dispose (assuming it's implemented), but you
you still might have several references to a invalid
object floating around. Alternatively you can take
advantage of the using statement IF the class implements
IDispose, however this can become unwieldy if you need
several nested using blocks.


You are not understanding the Dispose pattern. Dispose is only implemented
for classes that hold references to unmanaged resources - such as file
handles, window handles, database connections, socket handles, etc.)


Ahem, you don't seem to understand it fully either or I have
misunderstood it completely ;-). Whether a class implements
IDisposable or not has nothing to do with the class having *unmanaged*
resources. When a class implements IDisposable then it provides the
outside world with a means to deterministically clean up resources -
nothing more, nothing less. Some of these resources *might* be
unmanaged of course, but only might. For example, have a look at
System.IO.BinaryWriter. This class implements IDisposable but does
itself not have unmanaged resources. Among other (managed) data
members it owns a System.IO.Stream object and a buffer. The Dispose()
method is only there to flush that buffer and then close the
underlying stream. If you fail to call Dispose() before letting the
BinaryWriter object go out of scope you are guaranteed to lose some
data, because BinaryWriter does not have a finalizer. This is
intentional as you cannot access other managed objects (here: the
stream) in a finalizer. Why? Because the order of finalization of no
longer reachable objects is not defined. You might get lucky sometimes
but it's definitely not guaranteed to work.

Except for a few *very* esotheric cases, finalizers are only good to
clean up _unmanaged_ resources. E.g. if you have a look at
mscorlib.dll with ILDASM, you'll find that classes which have
unmanaged resources invariably also implement a finalizer. To avoid
code duplication, some of them combine finalization with disposal in a
pattern (the one with the virtual Dispose( bool dispose ) function).
Dispose() can be used to clean up managed *and* unmanaged resources
while Finalize() only releases the unmanaged resources.
These
are limmited OS resources, that need to be returned as soon as possible. In
other words, you don't want to wait around for your finalize method to be
called for those resources to be released.
True, but only part of the story, see above.
via the IDisposable interface. Generally all necessary clean up is called
from both the finalize method as well as the Dispose method, with the added
Finalize() only cleans up unmanaged resources, see above.

[snip] 2) Referecne counting is easy to screw up. Often they are implmented using
methods that increment or decrement the Ref count and it is up to the
developer or the runtime to make sure these are called in a balanced manner.


Yep, but it's also quite easy to get right. E.g. see

http://www.boost.org/libs/smart_ptr/shared_ptr.htm

Regards,

Andreas
Nov 13 '05 #5
"Andreas Huber" <ah****@gmx.net> wrote in message
news:3e**************************@posting.google.c om...
Finalize() only cleans up unmanaged resources, see above.


QUIZ : Why then Regex has a Finalizer ?
there is a ref counting mechanism under it
this approach is either extremely sophisticated (and i cannot understand
it) or extremely stupid
Nov 13 '05 #6
ncaHammer wrote:
"Andreas Huber" <ah****@gmx.net> wrote in message
news:3e**************************@posting.google.c om...
Finalize() only cleans up unmanaged resources, see above.


QUIZ : Why then Regex has a Finalizer ?
there is a ref counting mechanism under it
this approach is either extremely sophisticated (and i cannot
understand it) or extremely stupid


I've just had a look at the the class with ILDASM. This seems to be one of
the esotheric uses of finalizers I was talking about in the lines above the
one you quoted. Regex has a static HashTable field called "livecode". I'm
far from being proficient with MSIL so I don't really understand the code,
but it seems that all constructors put something in it while the destructor
(Finalizer) removes something from it. This is safe because the static data
member is supposed (guaranteed?) to exist at least as long as Regex objects.

Definitely, there are other uses for finalizers than just cleaning up
unmanaged resources. However, as I explained, you're quite limited in what
you can safely do with them. The other non-cleanup use I know uses
finalizers to implement an object pool and - no wonder - also only accesses
static data members in the finalizer.

I bet you won't find many such finalizers in the .NET framework.

Regards,

Andreas

Nov 13 '05 #7

"Andreas Huber" <ah****@gmx.net> wrote in message
news:3e**************************@posting.google.c om...
"Tom Shelton" <ts****@yahoo.com> wrote in message news:<#d**************@TK2MSFTNGP12.phx.gbl>...
"Ron James" <Ro*******@noapsm.rojacs.com> wrote in message
news:09****************************@phx.gbl...

[snip]
Unfortunately this is not so in C# (or Java) since you
cannot tell when the Garbage Collector will run. In C#
you can call Dispose (assuming it's implemented), but you
you still might have several references to a invalid
object floating around. Alternatively you can take
advantage of the using statement IF the class implements
IDispose, however this can become unwieldy if you need
several nested using blocks.


You are not understanding the Dispose pattern. Dispose is only implemented for classes that hold references to unmanaged resources - such as file
handles, window handles, database connections, socket handles, etc.)


Ahem, you don't seem to understand it fully either or I have
misunderstood it completely ;-). Whether a class implements
IDisposable or not has nothing to do with the class having *unmanaged*
resources. When a class implements IDisposable then it provides the
outside world with a means to deterministically clean up resources -
nothing more, nothing less. Some of these resources *might* be
unmanaged of course, but only might. For example, have a look at
System.IO.BinaryWriter. This class implements IDisposable but does
itself not have unmanaged resources. Among other (managed) data
members it owns a System.IO.Stream object and a buffer. The Dispose()
method is only there to flush that buffer and then close the
underlying stream. If you fail to call Dispose() before letting the
BinaryWriter object go out of scope you are guaranteed to lose some
data, because BinaryWriter does not have a finalizer. This is
intentional as you cannot access other managed objects (here: the
stream) in a finalizer. Why? Because the order of finalization of no
longer reachable objects is not defined. You might get lucky sometimes
but it's definitely not guaranteed to work.


Hello! BinaryWritter takes a stream as one of the arguments to both it's
public constructors... That stream is almost certainly going to have an
underlying OS resource - FileStream or NetworkStream for example. In other
words, though BinaryWriter doesn't itself contain a unmanaged resource, it
contains a class that does - hence the need for dispose.
Except for a few *very* esotheric cases, finalizers are only good to
clean up _unmanaged_ resources. E.g. if you have a look at
mscorlib.dll with ILDASM, you'll find that classes which have
unmanaged resources invariably also implement a finalizer. To avoid
code duplication, some of them combine finalization with disposal in a
pattern (the one with the virtual Dispose( bool dispose ) function).
Dispose() can be used to clean up managed *and* unmanaged resources
while Finalize() only releases the unmanaged resources.
What managed resources will you clean up with dispose? Setting internal
references to null isn't going to change anything... The only reason your
example above implements dispose is that is a generic wrapper for a stream.
A stream will almost certainly have a unmanaged resource at the root.
These
are limmited OS resources, that need to be returned as soon as possible. In other words, you don't want to wait around for your finalize method to be called for those resources to be released.


True, but only part of the story, see above.


Except that your story is wrong...
via the IDisposable interface. Generally all necessary clean up is called from both the finalize method as well as the Dispose method, with the added
Finalize() only cleans up unmanaged resources, see above.
Yes, that is what I said, except you have the part about Dispose wrong.
There is no reason to implement IDisposable if there are no unmanaged
resources to clean up. Think about it...
[snip]
2) Referecne counting is easy to screw up. Often they are implmented
using methods that increment or decrement the Ref count and it is up to the
developer or the runtime to make sure these are called in a balanced

manner.
Yep, but it's also quite easy to get right. E.g. see

http://www.boost.org/libs/smart_ptr/shared_ptr.htm


Yes, I am aware of smart pointers...

Tom Shelton
Nov 13 '05 #8

"Andreas Huber" <ah****@gmx.net> wrote in message
news:3f********@news.swissonline.ch...
ncaHammer wrote:
"Andreas Huber" <ah****@gmx.net> wrote in message
news:3e**************************@posting.google.c om...
Finalize() only cleans up unmanaged resources, see above.
QUIZ : Why then Regex has a Finalizer ?
there is a ref counting mechanism under it
this approach is either extremely sophisticated (and i cannot
understand it) or extremely stupid


I've just had a look at the the class with ILDASM. This seems to be one of
the esotheric uses of finalizers I was talking about in the lines above

the one you quoted. Regex has a static HashTable field called "livecode". I'm
far from being proficient with MSIL so I don't really understand the code,
but it seems that all constructors put something in it while the destructor (Finalizer) removes something from it. This is safe because the static data member is supposed (guaranteed?) to exist at least as long as Regex objects.
Definitely, there are other uses for finalizers than just cleaning up
unmanaged resources. However, as I explained, you're quite limited in what
you can safely do with them. The other non-cleanup use I know uses
finalizers to implement an object pool and - no wonder - also only accesses static data members in the finalizer.

I bet you won't find many such finalizers in the .NET framework.

Regards,

Andreas


Having not looked at the IDL for this, my guess form this is that it is
stashing the compiled regular expressions, and then removing them when they
are no longer needed. This I guess a form of cleanup, you have to remove a
reference to the compiled code or it would stay there for ever in the static
object. It is very similar to your reference to object pooling above.

Tom Shelton
Nov 13 '05 #9
"Tom Shelton" <ts****@yahoo.com> wrote in message
news:un**************@TK2MSFTNGP12.phx.gbl...
Yes, that is what I said, except you have the part about Dispose wrong.
There is no reason to implement IDisposable if there are no unmanaged
resources to clean up. Think about it...


All components implement IDisposable and most of them don't hold any
unmanaged resources.
At design time (or at runtime) Disposing a component should remove any
references that any component (under the ISite) holds for it. This action
should restore the ISite component graph to the state it had before adding
this component.

for example :

ToolbarButton while not holding any unmanaged resource, it does implement
IDisposable. Disposing a toolbarbutton it removes it from the button
collection of the toolbar.

I don't know if i make my point clear. (my English are bad)
In a nutshell. Dispose is also used to maintain an object graph consistent.
You can interpret it as "on-delete trigger" in SQL terms
Nov 13 '05 #10

"ncaHammer" <nc*******@nos.pamhot.mail.com> wrote in message
news:OG**************@TK2MSFTNGP11.phx.gbl...
"Tom Shelton" <ts****@yahoo.com> wrote in message
news:un**************@TK2MSFTNGP12.phx.gbl...
Yes, that is what I said, except you have the part about Dispose wrong.
There is no reason to implement IDisposable if there are no unmanaged
resources to clean up. Think about it...


All components implement IDisposable and most of them don't hold any
unmanaged resources.
At design time (or at runtime) Disposing a component should remove any
references that any component (under the ISite) holds for it. This action
should restore the ISite component graph to the state it had before adding
this component.

for example :

ToolbarButton while not holding any unmanaged resource, it does implement
IDisposable. Disposing a toolbarbutton it removes it from the button
collection of the toolbar.


Ok, not something I had thought about - still I'm looking throught IDL :)
This usage seems about as strange as the use of finalize for object pooling.
I can see though why a component would have a dispose method - they just
might have unmanaged resources. What about database components etc...

Tom Shelton
Nov 13 '05 #11

"Tom Shelton" <ts****@yahoo.com> wrote in message
news:%2****************@TK2MSFTNGP12.phx.gbl...

"ncaHammer" <nc*******@nos.pamhot.mail.com> wrote in message
news:OG**************@TK2MSFTNGP11.phx.gbl...
"Tom Shelton" <ts****@yahoo.com> wrote in message
news:un**************@TK2MSFTNGP12.phx.gbl...
Yes, that is what I said, except you have the part about Dispose wrong. There is no reason to implement IDisposable if there are no unmanaged
resources to clean up. Think about it...
All components implement IDisposable and most of them don't hold any
unmanaged resources.
At design time (or at runtime) Disposing a component should remove any
references that any component (under the ISite) holds for it. This action should restore the ISite component graph to the state it had before adding this component.

for example :

ToolbarButton while not holding any unmanaged resource, it does implement IDisposable. Disposing a toolbarbutton it removes it from the button
collection of the toolbar.


Ok, not something I had thought about - still I'm looking throught IDL :)
This usage seems about as strange as the use of finalize for object

pooling. I can see though why a component would have a dispose method - they just
might have unmanaged resources. What about database components etc...

Tom Shelton


Bye the way, I wouldn't say most components do not hold unmanaged
resources... Every winforms control is a component, since every control
inherits from component. I in fact would say that most components, do in
fact hold unmanaged resources (Controls, Timers, Connections, Messaging,
etc)

Tom Shelton
Nov 13 '05 #12
Tom Shelton wrote:
[snip]
Ahem, you don't seem to understand it fully either or I have
misunderstood it completely ;-). Whether a class implements
IDisposable or not has nothing to do with the class having
*unmanaged* resources. When a class implements IDisposable then it
provides the outside world with a means to deterministically clean
up resources - nothing more, nothing less. Some of these resources
*might* be
unmanaged of course, but only might. For example, have a look at
System.IO.BinaryWriter. This class implements IDisposable but does
itself not have unmanaged resources. Among other (managed) data
members it owns a System.IO.Stream object and a buffer. The Dispose()
method is only there to flush that buffer and then close the
underlying stream. If you fail to call Dispose() before letting the
BinaryWriter object go out of scope you are guaranteed to lose some
data, because BinaryWriter does not have a finalizer. This is
intentional as you cannot access other managed objects (here: the
stream) in a finalizer. Why? Because the order of finalization of no
longer reachable objects is not defined. You might get lucky
sometimes but it's definitely not guaranteed to work.
Hello! BinaryWritter takes a stream as one of the arguments to both
it's public constructors... That stream is almost certainly going to
have an underlying OS resource - FileStream or NetworkStream for


Counter example: A MemoryStream object does not hold unmanaged OS resources.
example. In other words, though BinaryWriter doesn't itself contain
a unmanaged resource, it contains a class that does - hence the need
for dispose.
Nope. You need to call Dispose() even if you pass a MemoryStream object to
the BinaryWriter constructor or you are almost guaranteed to lose data,
although there aren't any unmanaged resources anywhere.
Except for a few *very* esotheric cases, finalizers are only good to
clean up _unmanaged_ resources. E.g. if you have a look at
mscorlib.dll with ILDASM, you'll find that classes which have
unmanaged resources invariably also implement a finalizer. To avoid
code duplication, some of them combine finalization with disposal in
a pattern (the one with the virtual Dispose( bool dispose )
function). Dispose() can be used to clean up managed *and* unmanaged
resources
while Finalize() only releases the unmanaged resources.
What managed resources will you clean up with dispose?


As I tried to explain in my previous post, the problem is that BinaryWriter
itself holds a buffer. If you want the contents of that buffer to be flushed
into the stream, you *must* call Dispose(). ~BinaryWriter() (if it existed)
won't do that for you because the underlying stream might already be dead.
Whether or not the stream holds any unmanaged resources is simply
irrelevant.
If you fail to call Dispose() on the BinaryWriter object you will lose data,
even if the stream does not hold unmanaged resources.

[snip] Yes, that is what I said, except you have the part about Dispose
wrong. There is no reason to implement IDisposable if there are no
unmanaged resources to clean up. Think about it...


You are right in as much as that the managed resources will all be released
correctly. However, you are wrong in terms of correctness because the
released resources might hold valuable data, which will simply be thrown
away if you fail to call Dispose() before letting the object go out of
scope.

Regards,

Andreas

Nov 13 '05 #13
Andreas Huber wrote:
[snip]
Nope. You need to call Dispose() even if you pass a MemoryStream
object to the BinaryWriter constructor or you are almost guaranteed
to lose data, although there aren't any unmanaged resources anywhere.

[snip]

Forget about BinaryWriter, it does not have an internal buffer. Instead,
have a look at StreamWriter.

Regards,

Andreas

Nov 13 '05 #14
Hi Ron, gentlmen.

C++ is a great language. Agreed
the stack, grab whatever resources you need, and free them
in the destructor. Object destructors are called in the
correct order (the reverse order), and are guaranteed to
be called when the object goes out of scope.

As far as I can tell, you, as I had once, are missing the good old
"Resource acquisition is initialization (RAII)" idiom. Others have already
answered the technical reasons for choosing garbage collection instead of
reference counting, so I'll just keep my two cents on that subject to myself.
However, may I suggest that you take a look at the following article, which
does attempt to simulate the RAII idiom in C#:
http://www.codeproject.com/csharp/exceptions.asp

Hope you'd find it useful.

Sincerely,
LM.

P.S. My apologies to you and others how are viewing this post if I have broken
proper etiquette, since this is my first post to this group.
Nov 13 '05 #15

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

Similar topics

22
by: Ling Lee | last post by:
Hi all. I'm trying to write a program that: 1) Ask me what file I want to count number of lines in, and then counts the lines and writes the answear out. 2) I made the first part like this: ...
6
by: Geetha | last post by:
I searched in the Oracle documents what count (1) meant and I could not find an answer. Can some one explain what Oracle does internally when use count (1) VS count (*). Thank you very much in...
1
by: JD | last post by:
Hi guys I'm trying to write a program that counts the occurrences of HTML tags in a text file. This is what I have so far: #include <stdio.h> #include <stdlib.h> #include <string.h> ...
5
by: Eric Johannsen | last post by:
I have a simple object that inherits from CollectionBase and overrides the Count property: namespace MyTest { public class CollTest : System.Collections.CollectionBase { public override int...
23
by: Gary Wessle | last post by:
Hi I have a vector<charwhich looks like this (a d d d a d s g e d d d d d k) I need to get the biggest count of consecutive 'd'. 5 in this example I am toying with this method but not sure if...
1
by: heckstein | last post by:
I am working in Access 2002 and trying to create a report from our company's learming management system. I am not a DBA and most of my SQL knowledge has been self taught through trial and error. I...
22
by: MP | last post by:
vb6,ado,mdb,win2k i pass the sql string to the .Execute method on the open connection to Table_Name(const) db table fwiw (the connection opened via class wrapper:) msConnString = "Data Source="...
3
by: Auddog | last post by:
I have the following query that works in mysql: select id, order_no, price, count(item_no), sum(price) from production WHERE item_no = '27714' group by item_no; When I setup my query in php,...
7
by: Chris | last post by:
I am trying to increase/decrease the value of $_SESSION by 1 after clicking on a link e.g index.php?gotoWk=nxtWk and index.php? gotoWk=lstWk. I'm sure you will get the drift if you look at the code...
1
by: jlt206 | last post by:
This code <?php include("counter.php")?> on the webpage produces the count number. (function code below) I want to place the current number into a variable $MemberNo or into a FormField to be sent...
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
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
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
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,...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

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.