Toon posts:

[c++] Access privileges van local classes

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik snap niet waarom zowel C++ Builder 6 als Visual C++ 6 een error spugen op de aangegeven plaats in de volgende code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
struct B;

class A
{
  int i;

  friend B;
};

struct B
{
  void f ()
  {
    A().i;

    struct S
    {
    void g ()
    {
      A().i; // error: A::i not accessible (beide compilers)
    }
    };

    S().g();
  }
};

In de C++ standaard staat namelijk (9.8 Local Class Declarations, paragraaf 1):
The local class [...] has the same access to names outside the function as does the enclosing function.
Aangezien het accessen van A::i goed ging vanuit B::f, zou het dus ook goed moeten gaan vanuit S::g ..

Dus, wat doe ik fout ? (Het leek me een beetje te toevallig wanneer beide compilers er precies allebei op dezelfde manier naast zouden zitten..)

Verwijderd

De friend-clause is niet meer in scope is in de local class S (net zo als friend-access niet inherited wordt).

Probeer eens friend B::S toe te voegen aan class A.

  • frankvdtillaart
  • Registratie: November 2000
  • Laatst online: 24-05 07:42
Toevallig opgepikt toen ik door de MSDN aan het browsen was:

Class variabelen worden standaard gezien als "private".

Je zou dus kunnen proberen om:
Class A{
public:
int i;
private:
friend B;
}

of iets dergelijks.

Bij Structs zijn alle internen "standaard" al public.

Happy Blessings <3


Verwijderd

Topicstarter
Op donderdag 27 juni 2002 14:46 schreef RedSoniq wat.
Ik wil A::i niet public |:(.

Verwijderd

Op donderdag 27 juni 2002 14:46 schreef RedSoniq het volgende:
Toevallig opgepikt toen ik door de MSDN aan het browsen was:

Class variabelen worden standaard gezien als "private".

Je zou dus kunnen proberen om:
Class A{
public:
int i;
private:
friend B;
}

of iets dergelijks.

Bij Structs zijn alle internen "standaard" al public.
maar at compile time, zegt de compiler dat t een illegal friend definition is. het zou dus niet uitmaken of hij private of public is.

Verwijderd

Op donderdag 27 juni 2002 14:51 schreef Sneechy het volgende:

[..]

Ik wil A::i niet public |:(.
Natuurlijk niet :)

Dit is standaard gedrag voor de friend-clause, er gebeurt niets geks. Friends zijn zo restrictief mogelijk, zodat niet iedere jan met de korte achternaam aan de private parts van friends-of-friends kan komen (C++ joke met een lange baard).

Verwijderd

Topicstarter
Op donderdag 27 juni 2002 14:44 schreef mietje het volgende:
De friend-clause is niet meer in scope is in de local class S (net zo als friend-access niet inherited wordt).
Op donderdag 27 juni 2002 14:55 schreef mietje het volgende:
Dit is standaard gedrag voor de friend-clause, er gebeurt niets geks. Friends zijn zo restrictief mogelijk, zodat niet iedere jan met de korte achternaam aan de private parts van friends-of-friends kan komen (C++ joke met een lange baard).
Maar wat denk je dan van die quote van de standaard? Die zegt letterlijk dat de local class dezelfde access heeft als de enclosing function.

Een friend B::S; declaration toevoegen aan A lukt niet (en lijkt me ook niet zinnig, aangezien S gewoon f's access privileges zou moeten kunnen gebruiken).

Verwijderd

Topicstarter
Op donderdag 27 juni 2002 14:51 schreef Reflex het volgende:

[..]

maar at compile time, zegt de compiler dat t een illegal friend definition is. het zou dus niet uitmaken of hij private of public is.
Die illegal friend declaration error krijg ik noch met BC++, noch met VC++..

Verwijderd

Op donderdag 27 juni 2002 14:59 schreef Sneechy het volgende:

[..]

Die illegal friend declaration error krijg ik noch met BC++, noch met VC++..
CodeWarrior wel :)

en as said, is g++ er wel content mee

Verwijderd

Topicstarter
Op donderdag 27 juni 2002 15:00 schreef Reflex het volgende:
CodeWarrior wel :)

en as said, is g++ er wel content mee
Dat vind ik nog het vaagste, dat g++ 'm wel lust. Dat betekent dus dat of g++ er naast zit, of BC++ en VC++ er op precies hetzelfde punt naast zitten (en dat lijkt me wel _erg_ toevallig..).

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Local class is iets anders als nested class; als je kijkt zegt je quote notabene "enclosing function" !

Dit is een local class :
code:
1
2
3
4
5
void foo()
{
  class local_to_foo { };
  local_to_foo bar;
}

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
Op donderdag 27 juni 2002 15:03 schreef MSalters het volgende:
Local class is iets anders als nested class; als je kijkt zegt je quote notabene "enclosing function" !
Uhm, ik snap je niet..

In bovenstaande code maak ik gebruik van een local class, en die quote komt uit '9.8 Local Class Declarations'..

Verwijderd

Op donderdag 27 juni 2002 14:58 schreef Sneechy het volgende:
Maar wat denk je dan van die quote van de standaard? Die zegt letterlijk dat de local class dezelfde access heeft als de enclosing function.
Ik heb hier geen standaard bij de hand, maar ik weet zeker dat een friend-clause niet over class-grenzen heen geldt. Wat zegt de standaard letterlijk over friends?
Een friend B::S; declaration toevoegen aan A lukt niet (en lijkt me ook niet zinnig, aangezien S gewoon f's access privileges zou moeten kunnen gebruiken).
Oeps, je hebt gelijk. Als je hem friend maakt is hij niet local meer |:(

/me twijfelt nu zelf :)

Verwijderd

Topicstarter
Op donderdag 27 juni 2002 15:08 schreef mietje het volgende:
Ik heb hier geen standaard bij de hand, maar ik weet zeker dat een friend-clause niet over class-grenzen heen geldt. Wat zegt de standaard letterlijk over friends?
Een heleboel, maar ik kan geen uitzondering op de gequote regel vinden.

Verwijderd

Op donderdag 27 juni 2002 15:13 schreef Sneechy het volgende:
Een heleboel, maar ik kan geen uitzondering op de gequote regel vinden.
Damn, het lijkt erop dat je weer een compiler-bug gevonden hebt. Ik zal er vanavond eens over kouten met mijn guru, kijken wat die zegt :)

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op donderdag 27 juni 2002 15:04 schreef Sneechy het volgende:

[..]

Uhm, ik snap je niet..

In bovenstaande code maak ik gebruik van een local class, en die quote komt uit '9.8 Local Class Declarations'..
Nee, dat is een nested class (9.2/1) omdat het in een andere class B zit.
Local classes zitten in functies, kijk maar naar het voorbeeld van 9.8/1. Dwz het woord class (of struct) komt na de { van de functie implementatie.

edit:
Stukje standaard (11.4)[quote]
... the declarations of members of classes nested within the friend class cannot access the names of private and protected members from the class granting friendship.
[/quote]

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op donderdag 27 juni 2002 17:18 schreef MSalters het volgende:

[..]

Nee, dat is een nested class (9.2/1) omdat het in een andere class B zit.
Local classes zitten in functies, kijk maar naar het voorbeeld van 9.8/1. Dwz het woord class (of struct) komt na de { van de functie implementatie.
en om de logische vraag maar meteen te beantwoorden, een local class kun je niet benoemen ( func()::A of zo werkt niet ) terwijl B::S wel een extern zichtbare naam heeft.
Dus een local class kun je geen friend maken, en nested wel, en daarom erft een local class effectief de rechten van de omhullende functie

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op donderdag 27 juni 2002 17:18 schreef MSalters het volgende:

[..]

Nee, dat is een nested class (9.2/1) omdat het in een andere class B zit.
Local classes zitten in functies, kijk maar naar het voorbeeld van 9.8/1. Dwz het woord class (of struct) komt na de { van de functie implementatie.
kijk eens goed naar het stukje code van Sneechy, de struct S wordt gedeclareerd in de functie B::f (). Het is dan toch gewoon een local class (of struct in dit geval)?

of geldt het juist weer niet voor member-functies?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op donderdag 27 juni 2002 17:42 schreef .oisyn het volgende:

[..]

kijk eens goed naar het stukje code van Sneechy, de struct S wordt gedeclareerd in de functie B::f (). Het is dan toch gewoon een local class (of struct in dit geval)?

of geldt het juist weer niet voor member-functies?
Ik geloof dat dit het bewijs is dat X.25 hersenrot veroorzaakt. :( |:( Duh. Has een } na f gelezen.

't Is inderdaad een local class. Er zit een subtiliteitje in 9.8 :
" Declarations in a local class can use only type names, static variables, extern variables and functions, and enumerators from the enclosing scope. "

Dit moet je lezen als
" from the enclosing scope, Declarations in a local class can use only ...
niet als
"Declarations in a local class can use only names from the enclosing scope, and then only if... etc"

Dus A::i mag gebruikt worden vanuit B::f(), en in local classes van B::f() voor member declarations. Nu is een definitie ook een declaratie, dus de definitie van 'member of local class' S::g heeft de access rechten van B::f() en dat is o.a. A::i
edit:
dacht heel effe dat definitie != declaratie maar is subset/superset relatie

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Oh, het moet friend struct B; zijn.

http://www.comeaucomputing.com/tryitout/

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Topicstarter
Op donderdag 27 juni 2002 18:45 schreef MSalters het volgende:
Oh, het moet friend struct B; zijn.
Ah, dat verklaart dan Codewarrior's error (en eigenlijk is het dan weer een bug in de andere compilers dat ze die syntax toestaan |:().

Maar verder is de code dus correct en zitten BC++ en VC++ er uiteindelijk toch gezamenlijk naast ?

  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op donderdag 27 juni 2002 18:56 schreef Sneechy het volgende:

[..]

Ah, dat verklaart dan Codewarrior's error (en eigenlijk is het dan weer een bug in de andere compilers dat ze die syntax toestaan |:().

Maar verder is de code dus correct en zitten BC++ en VC++ er uiteindelijk toch gezamenlijk naast ?
Nee, als andere compilers het toestaan is het een extensie. En die ongedocumenteerde extensie geeft gewoon ander gedrag dan je had verwacht :Y)

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op donderdag 27 juni 2002 18:45 schreef MSalters het volgende:
Oh, het moet friend struct B; zijn.
waarom? Er is toch al aangegeven dat B een struct is? Dan hoeft het in de friend toch niet nog een keer?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 18:21
Op zondag 30 juni 2002 00:51 schreef .oisyn het volgende:
waarom? Er is toch al aangegeven dat B een struct is? Dan hoeft het in de friend toch niet nog een keer?
code:
1
2
3
4
5
6
struct id
{
  // ...
};

struct id variabele;

Waarom? Geen idee. Gaat zo bij de specificatie van het type bij variabele declaraties, dus ik neem aan dat het ook voor de specificatie van een friend-relatie geldt.

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03-09 13:30

.oisyn

Moderator Devschuur®

Demotivational Speaker

Op zondag 30 juni 2002 02:33 schreef Soultaker het volgende:

[..]
code:
1
2
3
4
5
6
struct id
{
  // ...
};

struct id variabele;

Waarom? Geen idee. Gaat zo bij de specificatie van het type bij variabele declaraties, dus ik neem aan dat het ook voor de specificatie van een friend-relatie geldt.
in C is dat idd zo (gebruik van een struct zonder typedef)
In C++ kun je echter gewoon dit doen:
code:
1
2
3
4
5
6
struct struct_t
{
    int i;
};

struct_t blaat;

Als je een class Klasse hebt die ergens een friend van is, dan doe je:
code:
1
2
3
4
class Blaat
{
    friend Klasse;
};

is Klasse echter nog niet gedeclareerd*, dan doe je
code:
1
2
3
4
5
6
class Klasse;

class Blaat
{
    friend Klasse;
};

of
code:
1
2
3
4
class Blaat
{
    friend class Klasse;
};

substitueer class voor struct, en zie daar: de eerste variant is precies zoals Sneechy m gebruikt, dus waarom moet je dan nog expliciet struct erbij zetten als je het type al gedeclareerd hebt?

* misschien verwar ik declareren met definieren... wat is nou wat?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 14:38

curry684

left part of the evil twins

Op donderdag 27 juni 2002 14:44 schreef mietje het volgende:
De friend-clause is niet meer in scope is in de local class S (net zo als friend-access niet inherited wordt).
Voor zover ik weet is dit gewoon de reden. Een friend-declaratie geldt per definitie alleen voor de specifieke named class, en heeft niets van doen met de standaard access specifiers. In dit geval is toegang tot die outer-class vanuit de local class niet mogelijk, ook niet met een friend. G++ zit er goed naast als ie dit slikt.
Probeer eens friend B::S toe te voegen aan class A.
Daar er in B wel duizenden local classes S gedefinieerd kunnen zijn is dit lichtelijk onmogelijk :Y)

Professionele website nodig?


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 14:38

curry684

left part of the evil twins

Op zondag 30 juni 2002 03:30 schreef .oisyn het volgende:
* misschien verwar ik declareren met definieren... wat is nou wat?
Declareren is het beweren dat iets bestaat.

Definieren is invullen hoe iets bestaat.

(zo onthoud ik het ;) )

Professionele website nodig?


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op zondag 30 juni 2002 00:51 schreef .oisyn het volgende:

[..]

waarom? Er is toch al aangegeven dat B een struct is? Dan hoeft het in de friend toch niet nog een keer?
De korte reden is dat de standaard het expliciet zegt.

De lange reden is (IIRC) dat de struct B buiten de class, dus in een andere scope staat, en dat de friend ook een nieuwe functie B() zou kunnen declareren (zelfs definieren). Om parsing problemen te voorkomen moet daarom een elaborated-type-specifier gebruikt worden.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op maandag 01 juli 2002 01:06 schreef curry684 het volgende:

[..]

Voor zover ik weet is dit gewoon de reden. Een friend-declaratie geldt per definitie alleen voor de specifieke named class, en heeft niets van doen met de standaard access specifiers. In dit geval is toegang tot die outer-class vanuit de local class niet mogelijk, ook niet met een friend. G++ zit er goed naast als ie dit slikt.
Een friend class declaratie geldt voor alle members van die class, inclusief die members die toevallig een local class definieren. En de local class heeft dezelfde access rights als de functie waarin die staat, ook als het toevallig een member functie is. Dus G++ heeft gewoon gelijk, EDG heeft gelijk, en VC/BCB zitten mis.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


  • MSalters
  • Registratie: Juni 2001
  • Laatst online: 22:38
Op maandag 01 juli 2002 01:07 schreef curry684 het volgende:

[..]

Declareren is het beweren dat iets bestaat.

Definieren is invullen hoe iets bestaat.
En om compleet te zijn: als je invult hoe iets bestaat heb je dus ook beweerd dat iets bestaat, oftewel een definitie is een declaratie.

Man hopes. Genius creates. Ralph Waldo Emerson
Never worry about theory as long as the machinery does what it's supposed to do. R. A. Heinlein


Verwijderd

Op maandag 01 juli 2002 01:06 schreef curry684 het volgende:
Daar er in B wel duizenden local classes S gedefinieerd kunnen zijn is dit lichtelijk onmogelijk :Y)
Ik maakte een fout door nested en local classes te verwarren (net als MSalters na mij ;) ), maar ik maak dit een post later alweer goed. Voor de rest lijkt het probleem ondertussen opgelost.
Pagina: 1