C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

3.4.5: qualified pseudodestructor call lookup rules fail
Goto page 1, 2, 3 ... 28, 29, 30  Next
 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
server
Guest





PostPosted: Thu Jan 26, 2006 5:23 pm    Post subject: 3.4.5: qualified pseudodestructor call lookup rules fail Reply with quote



message unavailable
Back to top
Guest






PostPosted: Thu Jan 26, 2006 5:23 pm    Post subject: Re: 3.4.5: qualified pseudodestructor call lookup rules fail Reply with quote



"Krzysztof Żelechowski" wrote:
Quote:
Please explain whether the following code is ill-formed:

typedef char T;

void fun(T &p_t) {
p_t.T::~T();
}

My reasoning goes as follows:
We have to lookup for T in the context of p_t.T by 3.4.3/5 . We have the
following choices by 3.4.5:
1. p_t is not of class type. N/A.
2. p_t is not of class type and is not a pointer to a scalar type. N/A.
3. T is not preceded by ~ and T::~T is qualified. N/A.
4. If T is a class-name-or-namespace-name. How can we tell? We have to
look it up to know what it is. It is a circular definition.
Assuming we could use some fixpoint logic to resolve this, there is no way
for T to be one. N/A.
5. T is not preceded by ::. N/A.
6. T is not followed by <. N/A.
7. T is not preceded by operator keyword (BTW a link to 12.3.2 is needed
here). N/A.
I am stuck.

The intent is that T in this example is looked up by an ordinary
lexical-scope lookup in the context of the complete postfix-expression.
However, you are right that the Standard does not contain a coherent
description of how this case (as well as a number of others with
respect to destructor and pseudo-destructor name lookup) is to be
handled. (See core language issues 244, 305, and 399, in particular.)

I'll open another issue for this case. Thanks for pointing it out.

-- William M. (Mike) Miller
Edison Design Group


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Martin Bonner
Guest





PostPosted: Thu Jan 26, 2006 6:13 pm    Post subject: Re: throw/catch and sequence points Reply with quote



Nick Maclaren wrote:
Quote:
Please do NOT answer it unless you have a more than casual knowledge
of the sequence point morass,

Sorry, I'm going to ignore that request.

Quote:
The simplest example is a function that evaluates an expression that
updates an object A while (not sequence-point separated) throwing an
exception B.

Somebody asked for example of such a piece of code. Does the following
qualify?

int global;
void g(int,int);
void f(int i)
{
g( global++, (i > 0?i:throw "negative i") );
}

Quote:
So I am right or confused?
or both?


---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Hyman Rosen
Guest





PostPosted: Thu Jan 26, 2006 7:06 pm    Post subject: Re: throw/catch and sequence points Reply with quote

Nick Maclaren wrote:
Quote:
(a = 0) + (b + c);
Where b+c overflows.

C++ exceptions are unrelated to overflow or other
such problems. If b+c overflows, then the code has
officially encountered undefined behavior, and the
standard says nothing at all about what this program
must do.

Some implementations do choose to convert such events
into C++ exceptions (and that's fine, since vendors
may choose to define undefined behavior for themselves),
and then you need to consult with them as to what they
have done for this case.

I would expect, given the lack of a sequence point here,
that you can make no assumptions about the state of 'a'
once the converted hardware exception is thrown.

I have argued elsewhere that the entire concept of
sequence points is misguided, and should be abandoned in
favor of a strict left-to-right order of evaluation with
side-effects happening as they are encountered. If this
were to be adopted, then you could be assured that a was
set when b + c threw. I'm glad you've added another point
in favor of my argument :-)

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Nick Maclaren
Guest





PostPosted: Thu Jan 26, 2006 7:47 pm    Post subject: Re: throw/catch and sequence points Reply with quote

In article <it5it1pe79fcqe7sj8vphf63tmgq293nuu (AT) 4ax (DOT) com>,
Bob Hairgrove <invalid (AT) bigfoot (DOT) com> wrote:
Quote:
On Thu, 26 Jan 2006 12:13:15 CST, "Martin Bonner"
martinfrompi (AT) yahoo (DOT) co.uk> wrote:

Somebody asked for example of such a piece of code. Does the following
qualify?

int global;
void g(int,int);
void f(int i)
{
g( global++, (i > 0?i:throw "negative i") );
}

Did you perhaps mean ++global ... ???

It makes no difference. Either update global, and there is no ordering
specified between that update and the conditional expression that
contains the throw.

Now, see my previous lecture about the different sequence point models
for the possible viewpoints on whether the sequence point at the '?'
is relevant or not :-)

To the other posters: please don't confuse the issue. I gave an example,
and kept it simple in order to keep it clear. Yes, I know all that,
but please see 1.9 paragraph 15 for where the standard says that this
may raise an exception. If you prefer, use the following:

(a = 0) + (throw "balls");

Yes, sequence points are fundamentally broken, but the simple solution
of lexicographic ordering conflicts with many forms of optimisation.
Simple left-to-right won't work, because of:

a = fred(a = 1);


Regards,
Nick Maclaren.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Sean Kelly
Guest





PostPosted: Thu Jan 26, 2006 10:52 pm    Post subject: Re: throw/catch and sequence points Reply with quote

Nick Maclaren wrote:
Quote:
In article <1138267396.096337.220330 (AT) g47g2000cwa (DOT) googlegroups.com>,
Sean Kelly <sean (AT) f4 (DOT) ca> wrote:

Why is this a problem? I would assume that in a multithreaded
environment, the exception would be handled by the same thread that
threw it, so memory synchronization should not be an issue in this
case. Is this incorrect?

Yes, on several grounds. Let's stick to the same thread, as it seems
that asynchronous exceptions are not something that C++ programmers
will swallow.

C/C++ sequence points apply only to one thread (obviously) and are
about memory synchronization. In particular, a compiler is allowed
to move memory operations around arbitrarily between them (subject
to doing the right operations), and is allowed to permit them to
be delayed by the hardware.

If there is no sequence point between the 'failing' function and the
handler, then the handler must not access anything accessed by the
failing function. Well, actually, if the handler is rooted at the
location of the catch, it must not access anything accessed in the
controlled clause. BAD news.

15.1.3 contains language that may indicate the presence of a sequence
point during the evaluation of the throw-expression:

"A throw-expression initializes a temporary object. . . [which] is used
to initialize
the variable named in the matching handler (15.3). . . Except for
these restrictions and the restrictions on type matching mentioned in
15.3, the operand of throw is treated exactly as a function argument in
a call (5.2.2) or the operand of a return statement."

Since at least one initialization is taking place here, surely a
sequence point must implicitly exist before the handler is evaluated.
And if not, perhaps the language could be strengthened to require one?
This seems like it may have more overall utility than trying to address
the issue in 1.9.17.

Quote:
I think he's referring to a memory barrier, which are used to order
memory accesses on SMP systems.

Not necessarily. The problems arise just as badly on serial systems
with loose memory ordering models, like the Alpha. If you look at
the code of pretty well any FLIH (first level interrupt handler),
you will see such things. Or, for the really ancient, the Model 91
pipeline drain instructions in IBM's Mod II Fortran library Smile

Seriously? I was under the impression that accesses would always be
observed in program order by the issuing processor. I would think that
anything weaker in this respect would be extremely difficult to program
for. Though I suppose this particular topic is better suited for a
different forum.

Quote:
This seems like a gray area at the moment. Since the current spec
assumes a single-threaded model, I don't believe there is any language
describing what a sequence point means in memory synchronization terms.

It doesn't even make sense on a SERIAL system Sad

It sounds like this memory model work is going to be even more fun than
I'd imagined Wink I do hope that something reasonable can be worked
out.


Sean

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Sergey P. Derevyago
Guest





PostPosted: Thu Jan 26, 2006 11:12 pm    Post subject: Re: Initialization of local static objects Reply with quote

Alberto Ganesh Barbati wrote:
Quote:
And 6.7p4 clearly stands: "A local object of POD type (3.9) with static
storage duration initialized with constant-expressions is initialized before
its block is first entered. An implementation is permitted to perform early
initialization of other local objects with static storage duration under the
same conditions that an implementation is permitted to statically initialize
an object with static storage duration in namespace scope (3.6.2). Otherwise
such an object is initialized the first time control passes through its
declaration;".

That is:
1. An implementation is permitted to initialize a local static object at the
first time control passes through its declaration.

Unless the object is of POD type initialized with a constant-expression,
because it's clearly stated in the sentence you quote that in that case
it must be "initialized before its block is first entered".

OK, let's put it another way. The phrase "before its block is first entered"

doesn't mean "before its surrounding function is first entered":

void f()
{
// obj can be initialized here, can't it?

{
POD obj=some_constant_expression;
}
}

Also, the phrase "before its block is first entered" from 6.7p4 doesn't equal
to the phrase "Objects of POD types (3.9) with static storage duration
initialized with constant expressions (5.19) shall be initialized before any
dynamic initialization takes place" from 3.6.2p1.
So local static mutex = PTHREAD_MUTEX_INITIALIZER initialization is
dangerous.

Quote:
2. And therefore local static pthread_mutex_t mutex =
PTHREAD_MUTEX_INITIALIZER ; is (potentially) thread-unsafe.
--

With all respect, Sergey. http://ders.angen.net/
mailto : ders at skeptik.net

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Bob Hairgrove
Guest





PostPosted: Thu Jan 26, 2006 11:23 pm    Post subject: Re: throw/catch and sequence points Reply with quote

On Thu, 26 Jan 2006 17:12:31 GMT, nmm1 (AT) cus (DOT) cam.ac.uk (Nick Maclaren)
wrote:

Quote:
|> Your simplest example could be made even more simple if you could
|> provide us with a piece of code. Without code it's very difficult (for
|> me, at least) to visualize the problem and follow you. In particular, I
|> cannot figure out how an expression could update an object and throw
|> without a separating sequence-point. I'm sure you have an example ready,
|> could you post it, please?

(a = 0) + (b + c);

Where b+c overflows. There are more complex examples that can occur
even in the cleanest of code.

Section 5, paragraph 5 says that the above is undefined behavior if
(b+c) overflows. The standard says nothing about hardware interrupts
or exceptions here. The assumption is that there would be a sequence
point at the semicolon.

Furthermore, the order of execution is unspecified: i.e., (a=0) can
be performed either before or after (b+c) on a conforming
implementation, and if (b+c) doesn't overflow, the result is
well-defined either way. And if it does overflow, the result is
undefined, also either way.

Note that if b and c are unsigned integers, there is no overflow, but
the value wraps (check out section 3.9.1, paragraph 4, footnote 41),
thus the expression's value is also well-defined. However, the same
caveats WRT hardware exceptions or signals apply.

--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Nick Maclaren
Guest





PostPosted: Fri Jan 27, 2006 12:22 am    Post subject: Re: throw/catch and sequence points Reply with quote

In article <1138267396.096337.220330 (AT) g47g2000cwa (DOT) googlegroups.com>,
Sean Kelly <sean (AT) f4 (DOT) ca> wrote:
Quote:

Why is this a problem? I would assume that in a multithreaded
environment, the exception would be handled by the same thread that
threw it, so memory synchronization should not be an issue in this
case. Is this incorrect?

Yes, on several grounds. Let's stick to the same thread, as it seems
that asynchronous exceptions are not something that C++ programmers
will swallow.

C/C++ sequence points apply only to one thread (obviously) and are
about memory synchronization. In particular, a compiler is allowed
to move memory operations around arbitrarily between them (subject
to doing the right operations), and is allowed to permit them to
be delayed by the hardware.

If there is no sequence point between the 'failing' function and the
handler, then the handler must not access anything accessed by the
failing function. Well, actually, if the handler is rooted at the
location of the catch, it must not access anything accessed in the
controlled clause. BAD news.

And it can get worse ....

Quote:
What almost all systems do, after the problem has bit badly enough
that they realise it must be fixed, is to put a barrier somewhere
around the throw/catch (it doesn't matter where). Unless I have
missed something critical, C++ needs to do the same.

Can you please give us a concrete example? What kind of barrier are
you referring to?

I think he's referring to a memory barrier, which are used to order
memory accesses on SMP systems.

Not necessarily. The problems arise just as badly on serial systems
with loose memory ordering models, like the Alpha. If you look at
the code of pretty well any FLIH (first level interrupt handler),
you will see such things. Or, for the really ancient, the Model 91
pipeline drain instructions in IBM's Mod II Fortran library :-)

Quote:
This seems like a gray area at the moment. Since the current spec
assumes a single-threaded model, I don't believe there is any language
describing what a sequence point means in memory synchronization terms.

It doesn't even make sense on a SERIAL system :-(

Quote:
I'm not sure I entirely understand the issue Nick is describing, but I
do believe it is indicative of questions that may arise as C++ 0x
memory model talk continues.

Spot on. And that is what I am involved with.


Regards,
Nick Maclaren,
University of Cambridge Computing Service,
New Museums Site, Pembroke Street, Cambridge CB2 3QH, England.
Email: nmm1 (AT) cam (DOT) ac.uk
Tel.: +44 1223 334761 Fax: +44 1223 334679

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Bob Hairgrove
Guest





PostPosted: Fri Jan 27, 2006 12:23 am    Post subject: Re: throw/catch and sequence points Reply with quote

On Thu, 26 Jan 2006 12:13:15 CST, "Martin Bonner"
<martinfrompi (AT) yahoo (DOT) co.uk> wrote:

Quote:
Somebody asked for example of such a piece of code. Does the following
qualify?

int global;
void g(int,int);
void f(int i)
{
g( global++, (i > 0?i:throw "negative i") );
}

Did you perhaps mean ++global ... ???

--
Bob Hairgrove
NoSpamPlease (AT) Home (DOT) com

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Guest






PostPosted: Fri Jan 27, 2006 12:32 am    Post subject: Re: throw/catch and sequence points Reply with quote

Nick Maclaren wrote:

Quote:
The simplest example is a function that evaluates an expression that
updates an object A while (not sequence-point separated) throwing an
exception B. One interpretation of sequence points is that the handler
is then called in a nonce sub-tree rooted at the point the exception
is raised. That is, actually, how a large proportion of hardware
works.

This means that there is no sequence-point ordering between the
update of A and the execution of the handler, and the programmer has
no power to introduce any.

In C++ there is a sequence point at the completion of the evaluation of
each full-expression (1.9/16). Throwing an exception is just another
way to end the evaluation of a full-expression (12.2/3). Therefore,
there is always a sequence point between the evaulation of a
throw-expression and entry into the corresponding catch block.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Hyman Rosen
Guest





PostPosted: Fri Jan 27, 2006 7:56 am    Post subject: Re: throw/catch and sequence points Reply with quote

Nick Maclaren wrote:
Quote:
please don't confuse the issue

Fundamentally, once you are in the exception handler,
yo have encountered the end-of-full-expression sequence
point, and the end-of-function sequence point if the
handler is in a different function. All side effects are
therefore settled. So there isn't any problem in the C++
standard related to this.

Quote:
Yes, sequence points are fundamentally broken, but the simple solution
of lexicographic ordering conflicts with many forms of optimisation.

We've been through this argument here many times, and no one
has presented any convincing evidence that this is the case.

Quote:
Simple left-to-right won't work, because of:
a = fred(a = 1);

The rule is (should be, rather)that in an expression, operands
are evaluated left to right, then the operation is done. Function
call expressions evaluate the function to be called, bind each
argument to its parameter left-to-right, then call the function.
Lvalue expressions bind to their object when evaluated. In your
example, we have
= a
fred
=
a
1
So first we evaluate lvalue a, then 'fred(a = 1)'. For the latter,
we evaluate fred, then evaluate the argument expression. For that,
we evaluate lvalue a, then 1, then perform the assignment. Then we
bind the result (generally a itself) to fred's first parameter. Then
we call fred, and assign the result to a.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Alberto Ganesh Barbati
Guest





PostPosted: Fri Jan 27, 2006 7:56 am    Post subject: Re: Initialization of local static objects Reply with quote

Sergey P. Derevyago ha scritto:
Quote:
Also, the phrase "before its block is first entered" from 6.7p4 doesn't equal
to the phrase "Objects of POD types (3.9) with static storage duration
initialized with constant expressions (5.19) shall be initialized before any
dynamic initialization takes place" from 3.6.2p1.

Although subclause 3.6.2 has title "Initialization of non-local
objects", the sentence you quote (from paragraph 1) applies to *all*
objects of POD types with static duration, so, perhaps surprisingly, it
applies also to local objects. At least that's my interpretation of the
sentence. This does not conflict with 6.7/4 although the wording there
is much weaker, as you noticed.

Quote:
So local static mutex = PTHREAD_MUTEX_INITIALIZER initialization is
dangerous.

Not if my interpretation is correct.

Ganesh

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Nick Maclaren
Guest





PostPosted: Fri Jan 27, 2006 7:56 am    Post subject: Re: throw/catch and sequence points Reply with quote

In article <GRZBf.38002$dW3.34874 (AT) newssvr21 (DOT) news.prodigy.com>,
John Nagle <nagle (AT) animats (DOT) com> writes:
|>
|> There are two basic problems worth thinking about here,
|> and it's not clear which one the original poster is trying
|> to discuss.
|>
|> First, there's the problem of converting a machine exception
|> into a C++ exception. C++, unlike Ada, does not generally
|> support that at all, although some implementations do try to
|> make it work. But that's a language extension.
|>
|> Second, there's the issue of what happens when the compiler
|> has introduced paralleism into a sequential program as an
|> optimization, and one of the threads throws an exception.
|> The original poster seems to be trying to figure out just
|> how conservative the C++ standard requires the compiler to be
|> in such situations. SGI has (had?) compilers which did such
|> optimizations, and so this problem is more than theoretical.

Nope. There is a third. Precisely what does the standard assume,
intend, require and forbid, is its wording complete, does it
express the intent, is it usable for its purpose and is it
implementable on important systems. And it is THAT which I am
trying to track down, and extend.

That level constrains the two you mentioned.


Regards,
Nick Maclaren.

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Alberto Ganesh Barbati
Guest





PostPosted: Fri Jan 27, 2006 12:55 pm    Post subject: Re: throw/catch and sequence points Reply with quote

John Nagle ha scritto:
Quote:
inline float f(float x)
{ ... } // expensive function with no side effects
// but which could raise an exception

float tab1[100000];
float tab2[100000];
...
for (int i=0; i<100000; i++)
{ tab2[i] = f(tab1[i]); }

A multithreading compiler might try to optimize this by putting
a few threads to work on the problem. That works out fine,
unless some call to f raises an exception. Should that occur,
"tab1" would be partially updated, but the updated elements
might not necessarily be sequential.

Are you sure such optimization is allowed? Wouldn't that violate 1.9/8?

Ganesh

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]
Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Goto page 1, 2, 3 ... 28, 29, 30  Next
Page 1 of 30

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.