Saturday, September 15, 2018

Digest for comp.lang.c++@googlegroups.com - 25 updates in 6 topics

Horizon68 <horizon@horizon.com>: Sep 15 10:25AM -0700

Hello..
 
 
My much enhanced Winmenus using wingraph and my Graph3D units and GUI
unit are here, and they work with Delphi and FreePascal and C++Builder
 
Now the following GUI components are supported:
 
- Winmenus
- TextBox
- Label
- MessageBox
- Button
 
 
Author: Amine Moulay Ramdane
 
I have implemented Winmenus using wingraph, this one is graphical, i
have also included an Opengl demo and other demos , just execute the
real3d1.exe executable inside the zipfile to see how it is powerful, i
will soon enhance much more my Winmenus.
 
Now it is both compatible with Delphi and with FreePascal, now
it works with Delphi tokyo, but there is only one difference between
Delphi and FreePascal, the double click with the left button of the
mouse of freepascal is replaced in Delphi with a one click with the
middle button of the mouse to avoid a problem.
 
Description:
 
Drop-Down Menu widget using the Wingraph unit. Please look at the
real3d1.pas demo inside the zip file to know how to use it.
 
Use the 'Delete' on the keyboard to delete the items
Use the 'Insert' on the keyboard to insert the items
and use the 'Up' and 'Down' and 'PageUp and 'PageDown' on the keyboard
to scroll ..
and use the 'Tab' on the keyboard to switch between the Drop Down Menus
and 'Enter' on the keyboard or mouse double click(for FreePascal) or
middle mouse click(for Delphi) to select an item..
and the 'Esc' on the keyboard or right mouse click to exit..
and the 'F1' on keyboard to delete all the items from the list
and right arrow and left arrow to scroll on the left or on the right
 
You can search with SearchName() and NextSearch() methods and now the
search with wildcards inside the Widget is working perfectly.
 
Winmenus is event driven, i have to explain it more to you to understand
more...
 
At first you have to create your Widget menu by executing something like
this:
 
Menu1:=TMenu.create(5,5);
 
This will create a Widget menu at the coordinate in characters (x,y) = (5,5)
 
After that you have to set your callbacks,cause my Winmenus is event
driven, so you have to do it like this:
 
Menu1.SetCallbacks(insert,updown);
 
The SetCallbacks() method will set your callbacks, the first callback
is the callback that will be executed when the insert key is pressed and
here above it is the "insert()" function, and the second callback is the
callback that will be called when the up and down keys are pressed and
here above it is the function "updown" , the remaining callbacks that
you can assign are the following keys: Delete and F1 to F12.
 
After that you have to set your callback function, cause my Winmenus is
event driven, so you have to add an item with AddItem() and set the
callback function at the same time, like this:
 
AddItem('First 3D opengl demo',test1);
 
test1 will be the callback function.
 
After that you will enter a loop like this , the template of this loop
must look like the following, that's not difficult to understand:
 
Here it is:
 
===
 
while true do
begin
if mouse1.click
then
begin
 
ret:=Menu.Execute(true);
if ret=ctExit
then
begin
break;
end;
Menu.Execute(false);
end;
end;
 
 
==
 
When you execute menu1.execute(false) with a parameter equal to false my
Winmenus widget will draw your menu without waiting for your input and
events, when you set the parameter of the execute() method to true it
will wait for your input and events, if the parameter of the execute
method is true and the returned value of the execute method is ctTab
that means you have pressed on the Tab key.. if the returned value is
ctExit that means you have pressed on the Escape key to exit.
 
I have also included my Graph3D unit for 3D graphism, and i have
included GUI.pas unit that comes with more GUI components, please look
at the demo.pas demo inside the zip file to know how to use my Winmenus
unit and GUI unit to do GUI.
 
About the Graph3D unit: it looks like the Graph unit of turbo pascal but
it's for 3D graphism, and to understand the variables Rho,Theta,Phi,DE
of the InitProj() method of Graph3D unit, please read what's below:
 
When you run the demo program that is called cube3d.pas , here is the
keys of the keyboard that permits you to run it:
 
Right arrow: to increase the angle Theta(that is the variable Theta) to
move in the plane XY anti-clockwise.
 
Left arrow: to decrease the angle Theta(that is the variable Theta) to
move in the plane XY clockwise.
 
Top arrow: to increase the Phi(that is variable Phi) angle to move up
and look at the cube from above.
 
Bottom arrow: to decrease the Phi(that is variable Phi) angle to move
down and look at the cube from below.
 
Key A: to decrease R(that is variable Rho) to get closer to the cube, we
can even penetrate it and pass behind, in the latter case the image
obtained will be the opposite.
 
Key E: to increase R(that is variable Rho) to move away from the cube.
 
Key +: to increase the distance D(that is variable DE) between the
screen and the eye, this causes an enlargement of the image.
 
Key -: to decrease the distance D(that is variable DE) between the
screen and the eye, this causes the image to shrink and possibly be an
inverse magnification if D becomes negative, ie if the screen passes
behind the observer.
 
Key C: to move from perspective projection to parallel projection and
vice versa. During this toggle the parameters which were current are
stored in auxiliary variables (RhoResp, DEResp for the perspective and
RhoPara, DEPara for the parallel projection) in order to be able to
return to it correctly afterwards.
 
Key F: To end the runnning program.
 
 
You can download the zip files for Delphi and FreePascal from:
 
https://sites.google.com/site/scalable68/winmenus-using-wingraph
 
 
Language: FPC Pascal v2.2.0+ / Delphi 7+: http://www.freepascal.org/
 
Operating Systems: Windows..
 
And the following define configurations inside the defines.inc file:
 
{$DEFINE CPU32} for 32 bit systems
 
{$DEFINE CPU64} for 64 bit systems
 
 
***********************************************************
IMPORTANT NOTE:
This software is provided 'as-is', without any express or
implied warranty. In no event will the author be held
liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for
any purpose, including commercial applications and redistribute it
freely, subject to the following restrictions:
 
1. The origin of this software must not be misrepresented,
you must not claim that you wrote the original software.
If you use this software in a product, an acknowledgment
in the product documentation would be appreciated but is
not required.
 
2. This notice may not be removed or altered from any
source distribution.
***********************************************************
 
If you make some money with my softwares in commercial projects, be kind
to make a donation to me in form of an amount of money. To make this
donation, please contact me by email and i will give you my personal
information to where you will send this donation.
 
Disclaimer:
 
This software is provided on an "as-is" basis, with no warranties,
express or implied. The entire risk and liability of using it is yours.
Any damages resulting from the use or misuse of this software will be
the responsibility of the user.
 
 
Thank you.
 
Amine Moulay Ramdane.
woodbrian77@gmail.com: Sep 15 10:04AM -0700

https://www.recode.net/2018/9/14/17857622/twitter-liberal-employees-conservative-trump-politics
 
As a Bopper (Biblically oriented programmer) I wouldn't
feel comfortable working for a lot of companies in 2018.
Years ago I worked at IBM and Southwest Airlines, but
their policies are no longer supportive of marriage
(one man + one woman) so I avoid these companies. I
realized in the 1990s that my back was against the wall
and I had no choice but to start a company. It hasn't
been easy as there have been a lot of attempts to undermine
the credibility of my company. But it's now 19 years later
and G-d has been faithful in terms of helping me build an
increasingly robust code base:
https://github.com/Ebenezer-group/onwards
 
. My message to conservative employees who don't feel
safe is to join smaller, more conservative companies.
For example, DuckDuckGo -- https://duckduckgo.com
 
is a good alternative to Google. They don't track your
searching and they don't follow you around with ads.
I've been using them for over ten years and never had a
problem with them.
 
If you are a conservative at Twitter, Facebook, etc.,
don't be fooled by these words from the Twitter CEO.
I think he feels bad about the situation, but don't think
he will do anything to really improve matters for you.
You will be left with difficult choices similar to what
I faced in the 1990s. If you decide to walk away from
Twitter, IBM, Facebook, etc.:
 
1. Congratulations. I think you will be happier in the
long run.
 
2. I'm willing to spend 16 hours/week for six months on a
project that uses my software. You can also refer yourself
and get a referral bonus. See http://webEbenezer.net/about.html
for more details.
 
 
 
Brian
Ebenezer Enterprises - Enjoying programming again.
http://webEbenezer.net
ram@zedat.fu-berlin.de (Stefan Ram): Sep 15 04:08PM

Alf P. Steinbach quotes C++17 §20.5.4.3:
>(1.1) macros
>(1.2) global names
>(1.3) names with external linkage
 
With
 
#define MACRO 1
 
I have declared the macro name »MACRO«.
Is this now reserved by the C ++ standard library by 1.1?
 
Or does one have to add: "... whenever one of those name was
declared or defined by the C ++ standard library" to the
quoted text?
 
A corresponding wording from 2176 (C) might be
 
|Each header declares or defines all identifiers listed in its
|associated subclause, and optionally declares or defines
|identifiers listed in its associated future library
|directions subclause and identifiers which are always
|reserved either for any use or for use as file scope
|identifiers.
Paul <pepstein5@gmail.com>: Sep 15 03:25AM -0700

Using gcc, the below code prints 0 on the console.
Why does it decide that I mean the user-defined pow
rather than the pow defined in cmath?
 
(Note that cmath defines a version of pow that is
not in the std namespace. If I comment out the
user-defined pow, I get the obvious 16384.)
 
Many thanks for your help.
 
#include <cmath>
#include <iostream>
 
double pow(int x, int y)
{
return 0;
}
 
int main()
{
std::cout << pow(4, 7);
return 0;
}
Ian Collins <ian-news@hotmail.com>: Sep 15 10:38PM +1200

On 15/09/18 22:25, Paul wrote:
> Using gcc, the below code prints 0 on the console.
> Why does it decide that I mean the user-defined pow
> rather than the pow defined in cmath?
 
Because you are passing two int parameters. If you change your call to
use doubles, you will match std::pow.
 
> (Note that cmath defines a version of pow that is
> not in the std namespace. If I comment out the
> user-defined pow, I get the obvious 16384.)
 
What's 16384?
 
 
--
Ian.
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Sep 15 12:39PM +0200

On 15.09.2018 12:25, Paul wrote:
> Using gcc, the below code prints 0 on the console.
> Why does it decide that I mean the user-defined pow
> rather than the pow defined in cmath?
 
Your user-defined one, with `int` formal arguments, is a more specific
overload for the arguments used in the call.
 
 
> (Note that cmath defines a version of pow that is
> not in the std namespace.
 
With your compiler's implementation of the standard library `<cmath>`
defines the overloads of `pow` in the global namespace, but not
necessarily with some other compiler's implementation.
 
This is not portable code.
 
 
> If I comment out the user-defined pow, I get the obvious 16384.)
 
Or you can change the call to e.g. `pow( 4., 7)`.
 
 
> std::cout << pow(4, 7);
> return 0;
> }
 
Mostly a cosmetics issue, but an explicit `return 0;` is redundant; it's
the default for `main`.
 
A side-issue: you can define an integer `pow` that's much faster than
the general `pow` for floating point numbers. The general idea is to use
repeated squaring via Horner's rule for calculating polynomials. OK that
description may sound as if it's very complicated; it's not.
 
 
Cheers & hth.,
 
- Alf
Ian Collins <ian-news@hotmail.com>: Sep 15 10:40PM +1200

On 15/09/18 22:38, Ian Collins wrote:
>> not in the std namespace. If I comment out the
>> user-defined pow, I get the obvious 16384.)
 
> What's 16384?
 
The expected answer, ignore that comment!
--
Ian.
Ian Collins <ian-news@hotmail.com>: Sep 15 10:42PM +1200

On 15/09/18 22:39, Alf P. Steinbach wrote:
 
> This is not portable code.
 
>> If I comment out the user-defined pow, I get the obvious 16384.)
 
> Or you can change the call to e.g. `pow( 4., 7)`.
 
That won't match either...
 
--
Ian.
David Brown <david.brown@hesbynett.no>: Sep 15 01:11PM +0200

On 15/09/18 12:40, Ian Collins wrote:
>>> user-defined pow, I get the obvious 16384.)
 
>> What's 16384?
 
> The expected answer, ignore that comment!
 
Don't you know your 4-power's table? Back to the school bench with you,
boy!
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Sep 15 01:30PM +0200

On 15.09.2018 12:42, Ian Collins wrote:
>> [snip]
>> Or you can change the call to e.g. `pow( 4., 7)`.
 
> That won't match either...
 
Works for me. Why did you think it wouldn't match?
 
 
Cheers!,
 
- Alf
Paul <pepstein5@gmail.com>: Sep 15 04:52AM -0700

On Saturday, September 15, 2018 at 11:39:44 AM UTC+1, Alf P. Steinbach wrote:
> the general `pow` for floating point numbers. The general idea is to use
> repeated squaring via Horner's rule for calculating polynomials. OK that
> description may sound as if it's very complicated; it's not.
 
I'm familiar with the implementation of pow you describe.
You go through a loop and do exponent >>= 1; base *= base at each
iteration until exponent reaches 0. if exponent is odd, then an extra
result *= base step is required.
 
Below code prints 0 with gcc. This surprises me because
it calls the user-defined version of pow in response to std::pow.
I'd expect it to print 16384.
 
#include <cmath>
#include <iostream>
 
double pow(double x, double y)
{
return 0;
}
 
int main()
{
std::cout << std::pow(4.0, 7.0);
}
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Sep 15 02:10PM +0200

On 15.09.2018 13:52, Paul wrote:
> {
> std::cout << std::pow(4.0, 7.0);
> }
 
Formally the explanation is that it's Undefined Behavior where anything
(including nothing) can happen, because
 
C++17 §20.5.4.3
<quote>
The C ++ standard library reserves the following kinds of names:
 
(1.1) macros
(1.2) global names
(1.3) names with external linkage
 
If a program declares or defines a name in a context where it is
reserved, other than as explicitly allowed by this Clause, its behavior
is undefined.
</quote>
 
From an in-practice view what happens is probably that the mechanism
that allows you to define overrides of e.g. `operator new`, kicks in
also for this (with your compiler) redefinition of a `pow` overload.
 
That was a nifty example, new to me. Thanks. :)
 
 
Cheers!,
 
- Alf
Paul <pepstein5@gmail.com>: Sep 15 05:35AM -0700

On Saturday, September 15, 2018 at 1:11:06 PM UTC+1, Alf P. Steinbach wrote:
 
> From an in-practice view what happens is probably that the mechanism
> that allows you to define overrides of e.g. `operator new`, kicks in
> also for this (with your compiler) redefinition of a `pow` overload.
 
I thought that the standard way of swapping was
using std::swap;
swap(a, b);
 
and that this means "Use the user-implemented version of swap
if it exists. Otherwise use std::swap".
So why isn't this undefined behaviour too? It seems very similar to my
code.
 
Paul
Paavo Helde <myfirstname@osa.pri.ee>: Sep 15 05:19PM +0300

On 15.09.2018 15:35, Paul wrote:
> if it exists. Otherwise use std::swap".
> So why isn't this undefined behaviour too? It seems very similar to my
> code.
 
std::swap is a template, which is only considered as a fallback in case
there is no ordinary function with an exactly matching signature.
 
pow(double, double) on the other hand is an ordinary function so
defining your own pow(double, double) may cause UB (depending on whether
<cmath> defines pow(double, double) in the global namespace or not,
which is unspecified).
 
So, what you have got is "unspecified UB" ;-)
Ben Bacarisse <ben.usenet@bsb.me.uk>: Sep 15 03:20PM +0100

>> reserved, other than as explicitly allowed by this Clause, its behavior
>> is undefined.
>> </quote>
<snip>
> if it exists. Otherwise use std::swap".
> So why isn't this undefined behaviour too? It seems very similar to my
> code.
 
The difference is that the header that defines std::swap does not also
define swap.
 
I still find your example curious because, though it is UB, a reason
often given for why the standard reserves names is so that it can assume
that the standard version is meant!
 
--
Ben.
Manfred <noname@add.invalid>: Sep 15 04:41PM +0200

On 9/15/2018 2:10 PM, Alf P. Steinbach wrote:
> reserved, other than as explicitly allowed by this Clause, its behavior
> is undefined.
> </quote>
 
I don't think it is undefined behavior, it is a matter of function
replacement instead (20.3.19 and 20.5.4.6).
The program creation process (5.2, p.9) specifies that library linkage
is performed last, so that all extern function definitions provided by
the program itself are used instead of the library supplied ones.
 
In the case of pow(), in glibc it is defined it in <math.h> in the
global namespace, and imported into std via 'using ::pow;" by <cmath>,
which explains why the one supplied by the program in the global
namespace overrides the library provided one even in namespace std.
 
 
 
> From an in-practice view what happens is probably that the mechanism
> that allows you to define overrides of e.g. `operator new`, kicks in
> also for this (with your compiler) redefinition of a `pow` overload.
This is in 20.5.4.6
 
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Sep 15 04:47PM +0200

On 15.09.2018 14:35, Paul wrote:
> if it exists. Otherwise use std::swap".
> So why isn't this undefined behaviour too? It seems very similar to my
> code.
 
A `using` declaration is formally a declaration, but the above `using`
declaration is not "in a context where [the name] is reserved", and
also, the /intent/ of the standard is clearly to prohibit user
redefinitions of names provided by the standard library, it's just a
less than perfect too inclusive wording when it's viewed as formalism.
 
The reserved context for `std::swap` is namespace `std`. There is no
global namespace counterpart. The global namespace counterpart for e.g.
`std::pow` is there for C compatibility, because `pow` was introduced in
C, and C has nothing like the C++ `std::swap`.
 
You know that a standard library header comes originally from C when
there is a <cFOO> or <FOO.h> variant of it.
 
---
 
So what happens if you put that `using` declaration in namespace `std`,
where the name is reserved?
 
In practice a compiler would have to be so called ¹"perverse" in order
to diagnose that, or to do anything ungood. It just affirms that the
name exists in this context, which it does. But formally the wording of
§20.5.4.3 is sufficiently unclear, using just the word "declares", that
I think it would be formally UB.
 
Then we're over in language lawyer territory. So called because like
some aspects of the law and religious texts it's mostly about getting
consensus (or usually, not!) about interpretations of subtle points that
do not really matter in practical programming. :)
 
---
 
I'm sorry that I didn't notice the UB in the very first example.
 
That's because it had an immediate and clear practical explanation, in
terms of overload resolution.
 
 
Cheers!,
 
- Alf
 
Notes:
¹ The notion of a "perverse" compiler also originated with C, as a way
to write maximally portable code, namely a compiler that would do its
utmost to detect UB and system dependencies and give formally permitted
but completely impractical results, but I've looked for the original
discussion for some time now and the articles seem to have disappeared.
Manfred <noname@add.invalid>: Sep 15 04:54PM +0200

On 9/15/2018 4:20 PM, Ben Bacarisse wrote:
 
> I still find your example curious because, though it is UB, a reason
> often given for why the standard reserves names is so that it can assume
> that the standard version is meant!
 
Adding to what I wrote in another post (I don't think it is UB), the
section about reserved names says:
20.5.4.3.3 External linkage
...
p. 2
Each global function signature declared with external linkage in a
header is reserved to the implementation to designate that function
signature with external linkage.
...
p. 4
Each function signature from the C standard library declared with
external linkage is reserved to the implementation for use as a function
signature with both extern "C" and extern "C++" linkage...
 
Which I read as 'pow' being reserved as a 'function signature' with the
actual function definition subject to replacement by the program itself.
Do I understand it wrong?
 
 
 
"Alf P. Steinbach" <alf.p.steinbach+usenet@gmail.com>: Sep 15 05:00PM +0200

On 15.09.2018 16:41, Manfred wrote:
>> behavior is undefined.
>> </quote>
 
> I don't think it is undefined behavior
 
Clearly `pow` is a global name in the standard library.
 
And that's regardless of whether it's declared as such by the included
headers.
 
And given that it's a global name in the standard library, the above
quoted paragraph says that it's UB to declare or define it in the global
namespace, a "context where it is reserved".
 
 
>, it is a matter of function
> replacement instead (20.3.19 and 20.5.4.6).
 
I agree that in practice it is apparently a matter of function
replacement, but the standard, via C++17 20.5.4.6 "Replacement
functions" that you refer to, only supports replacement of functions
from the `<new` header, such as the `operator new` allocation function.
 
 
> global namespace, and imported into std via 'using ::pow;" by <cmath>,
> which explains why the one supplied by the program in the global
> namespace overrides the library provided one even in namespace std.
 
Yes, agreed, that's most probably what happens in practice.
 
 
>> that allows you to define overrides of e.g. `operator new`, kicks in
>> also for this (with your compiler) redefinition of a `pow` overload.
> This is in 20.5.4.6
 
Yes, thanks.
 
 
>> That was a nifty example, new to me. Thanks. :)
 
 
Cheers!,
 
- Alf
Manfred <noname@add.invalid>: Sep 15 05:30PM +0200

On 9/15/2018 5:00 PM, Alf P. Steinbach wrote:
 
> And given that it's a global name in the standard library, the above
> quoted paragraph says that it's UB to declare or define it in the global
> namespace, a "context where it is reserved".
 
The fact is that 20.5.4.3.3 (under 20.5.4.3 that you mention) says that
'pow' is "reserved to the implementation to designate that function
signature with external linkage"
So, the name 'pow' is reserved to designate a function /signature/.
It clearly forbids to define, say, a global variable named 'pow', it is
not that clear that it forbids a program-provided implementation of that
function, provided it keeps the same signature.
 
> replacement, but the standard, via C++17 20.5.4.6 "Replacement
> functions" that you refer to, only supports replacement of functions
> from the `<new` header, such as the `operator new` allocation function.
20.5.4.6 p.1 mentions "clauses from 21 through 33 and annex D", which
would suggest quite a broad scope.
 
Nonetheless, you are most probably right on UB due to 20.3.22 (involved
in the definition of replacement function 20.3.19) which defines a
"reserved function":
a function, specified as part of the C++ standard library, that must be
defined by the implementation [ Note: If a C++ program provides a
definition for any reserved function, the results are undefined. —end note ]
 
So, if pow() is a function that must be defined by the implementation,
replacing it results in UB.
This makes sense, since other standard library functions may rely on
(possibly implementation-defined) properties of pow() that, if replaced,
may break the behavior of such other functions.
 
Paul <pepstein5@gmail.com>: Sep 15 07:37AM -0700

learncpp.com says:
 
(std::cout << (x > y)) ? x : y;
prints 1 (true) if x > y, or 0 (false) otherwise!
 
Experimentation on my computer shows that this is (unsurprisingly) correct.
However, I can't follow that logic.
std::cout << 0; returns std::cout in a healthy state
so std::cout << 0; should evaluate to true.
Also std::cout << 1; should evaluate to true;
 
So my expectation would be that (std::cout << (x > y)) ? x : y;
always prints 1
 
What am I missing?
 
Paul
Paul <pepstein5@gmail.com>: Sep 15 07:46AM -0700

On Saturday, September 15, 2018 at 3:37:38 PM UTC+1, Paul wrote:
> Also std::cout << 1; should evaluate to true;
 
> So my expectation would be that (std::cout << (x > y)) ? x : y;
> always prints 1
 
Sorry, I get it now -- the ternary operator always resolves to x for the
reasons I said.
But the text is only talking about the printout --- the printout is
just std::cout<< (x > y) which is what the text says.
 
Paul
"Chris M. Thomasson" <invalid_chris_thomasson@invalid.invalid>: Sep 14 07:47PM -0700

On 9/14/2018 3:49 PM, Paul wrote:
>> Co>
 
>> Well what is ur compiler? ???
 
> Code Blocks with C++11 enabled.
 
What compiler is Code Blocks using? I am guessing GCC right?
bitrex <user@example.net>: Sep 14 05:35PM -0400

On 09/14/2018 03:45 PM, Paul wrote:
> How can this designation be optional?
 
> Thanks for your help.
 
> Paul
 
Well what is ur compiler? ???
 
IDK
Paul <pepstein5@gmail.com>: Sep 15 03:27AM -0700

On Saturday, September 15, 2018 at 3:47:34 AM UTC+1, Chris M. Thomasson wrote:
 
> >> Well what is ur compiler? ???
 
> > Code Blocks with C++11 enabled.
 
> What compiler is Code Blocks using? I am guessing GCC right?
 
Yes, good point for clarity. Code Blocks is an IDE, not a compiler.
GCC is the compiler.
Thanks also to Alf Steinbach for excellent analysis, and thanks to
bitrex, too.
 
Paul
You received this digest because you're subscribed to updates for this group. You can change your settings on the group membership page.
To unsubscribe from this group and stop receiving emails from it send an email to comp.lang.c+++unsubscribe@googlegroups.com.

No comments: