Thread overview
"private:" remains in effect after end of containing attribute{}
Apr 06, 2007
Frits van Bommel
Apr 06, 2007
Daniel Keep
Apr 06, 2007
Bill Baxter
Apr 07, 2007
janderson
April 06, 2007
Something I ran into today:
=====
$ cat test.d
import std.stdio;
import a;

void main()
{
    auto a = new A;
    writefln(a.b);
}
$ cat a.d
struct A {
    final {
        private:
        int a;
    }
    static bool b;
}
$ dmd test.d a.d
test.d(7): struct a.A member b is not accessible
=====
(After commenting out the "private:" line it compiles fine)

Is that error supposed to happen?
Shouldn't the one of the block endings stop the "private:" from remaining in effect afterwards?

The spec seems to be very clear on this. http://www.digitalmars.com/d/attribute.html says the "attribute:" syntax "affects all declarations until the next }".

(Note that I recently filed bug #1090 (http://d.puremagic.com/issues/show_bug.cgi?id=1090) to change that sentence since as it stands now things like "version(Windows) { extern(Windows): }" should technically have no effect on anything, though the compiler doesn't implement it that way)

Since IMHO either that sentence or the compiler should be changed anyway, perhaps there should be some discussion about /which/ closing }'s should end the effects of an "attribute:" line.
Any thoughts?
April 06, 2007

Frits van Bommel wrote:
> Something I ran into today:
> =====
> $ cat test.d
> import std.stdio;
> import a;
> 
> void main()
> {
>     auto a = new A;
>     writefln(a.b);
> }
> $ cat a.d
> struct A {
>     final {
>         private:
>         int a;
>     }
>     static bool b;
> }
> $ dmd test.d a.d
> test.d(7): struct a.A member b is not accessible
> =====
> (After commenting out the "private:" line it compiles fine)
> 
> Is that error supposed to happen?
> Shouldn't the one of the block endings stop the "private:" from
> remaining in effect afterwards?
> 
> The spec seems to be very clear on this. http://www.digitalmars.com/d/attribute.html says the "attribute:" syntax "affects all declarations until the next }".
> 
> (Note that I recently filed bug #1090
> (http://d.puremagic.com/issues/show_bug.cgi?id=1090) to change that
> sentence since as it stands now things like "version(Windows) {
> extern(Windows): }" should technically have no effect on anything,
> though the compiler doesn't implement it that way)
> 
> Since IMHO either that sentence or the compiler should be changed
> anyway, perhaps there should be some discussion about /which/ closing
> }'s should end the effects of an "attribute:" line.
> Any thoughts?

I believe this is because it *should* say: "affects all declarations
until the end of the scope", and "final { ... }" doesn't introduce a scope.

	-- Daniel

-- 
int getRandomNumber()
{
    return 4; // chosen by fair dice roll.
              // guaranteed to be random.
}

http://xkcd.com/

v2sw5+8Yhw5ln4+5pr6OFPma8u6+7Lw4Tm6+7l6+7D i28a2Xs3MSr2e4/6+7t4TNSMb6HTOp5en5g6RAHCP  http://hackerkey.com/
April 06, 2007
Daniel Keep wrote:
> 
> I believe this is because it *should* say: "affects all declarations
> until the end of the scope", and "final { ... }" doesn't introduce a scope.

These non-scope curly braces have always made me uneasy.  Makes it difficult for my C++-adjusted eyes to tell at a glance what's still active and what's not.  I guess C++ has the "namespace {}" non-scope block, but that's only used at the top level scope so use cases can't get too complicated.

As for an alternative, I guess you could play around with alternate block delimiters for non-scope blocks

static if (is(foo==bar)) <<
    writefln("hello world")
>>

static if (is(foo==bar)) :{
    writefln("hello world")
}:

static if (is(foo==bar)) |{
    writefln("hello world")
}|

static if (is(foo==bar)) ::
    writefln("hello world")
::

I kind of like ':{ }:'  The colons are like a dotted line, a 1-D sieve if you will, indicating that things can 'pass through' this block.  Also meshes well with the non-scoping tags like "private:"

You could phase it in with three-step plan:
1) add :{ }: (or whatever) as an alternate syntax which can be used for "non-scope block" in the current non-scope contexts (static if, version, public etc)

2) deprecate/warn about uses of plain {} with non-scope blocks.

3) make plain {} with non-scope blocks an error.

4) Finally, reintroduce the ability to use {} with things like static if, but this time have them really create a scope (where a scope makes sense). This way we can ultimately get back to the shiny happy rule of '{ }' always makes a scope whenever it can.

On the other hand, no one else seems to be bothered by this but me.   I thought I'd get this off my chest anyway.  :-)

--bb
April 07, 2007
Bill Baxter wrote:
> Daniel Keep wrote:
>>
>> I believe this is because it *should* say: "affects all declarations
>> until the end of the scope", and "final { ... }" doesn't introduce a scope.
> 
> These non-scope curly braces have always made me uneasy.  Makes it difficult for my C++-adjusted eyes to tell at a glance what's still active and what's not.  I guess C++ has the "namespace {}" non-scope block, but that's only used at the top level scope so use cases can't get too complicated.
> 
> As for an alternative, I guess you could play around with alternate block delimiters for non-scope blocks
> 
> static if (is(foo==bar)) <<
>     writefln("hello world")
>  >>
> 
> static if (is(foo==bar)) :{
>     writefln("hello world")
> }:
> 
> static if (is(foo==bar)) |{
>     writefln("hello world")
> }|
> 
> static if (is(foo==bar)) ::
>     writefln("hello world")
> ::
> 
> I kind of like ':{ }:'  The colons are like a dotted line, a 1-D sieve if you will, indicating that things can 'pass through' this block.  Also meshes well with the non-scoping tags like "private:"
> 
> You could phase it in with three-step plan:
> 1) add :{ }: (or whatever) as an alternate syntax which can be used for "non-scope block" in the current non-scope contexts (static if, version, public etc)
> 
> 2) deprecate/warn about uses of plain {} with non-scope blocks.
> 
> 3) make plain {} with non-scope blocks an error.
> 
> 4) Finally, reintroduce the ability to use {} with things like static if, but this time have them really create a scope (where a scope makes sense). This way we can ultimately get back to the shiny happy rule of '{ }' always makes a scope whenever it can.
> 
> On the other hand, no one else seems to be bothered by this but me.   I thought I'd get this off my chest anyway.  :-)
> 
> --bb

This is a good idea.  I've been bothered by the non-bracketable static ifs as well.  I think the smilely faces are the easiest to read.

-Joel