A missing language feature?

  • Thread starter Alf P. Steinbach
  • Start date
A

Alf P. Steinbach

I think it's a language defect, or at least an inconsistency, that a definition
of F generally can't use the same type names as the earlier declaration of F.

The source of this problem is that by current rules the compiler evaluates the
routine result type declaration before knowing which routine it's compiling: the
result type, as opposed to argument types, is not evaluated in the routine's
declaration context.

It would IMHO be nice with consistent rules, the same rules, for arguments and
result types.


Cheers,

- Alf (grumbling)


PS: Of course, an even more missing language feature is some sort of module
support. The administrative overhead of using libraries in C++, specifying
header and library search paths, binary names etc., is O(n^2) where n is the
number of libraries that are being developed within a project. That's silly.
 
S

Saeed Amrollahi

I think it's a language defect, or at least an inconsistency, that a definition
of F generally can't use the same type names as the earlier declaration of F.

The source of this problem is that by current rules the compiler evaluates the
routine result type declaration before knowing which routine it's compiling: the
result type, as opposed to argument types, is not evaluated in the routine's
declaration context.

It would IMHO be nice with consistent rules, the same rules, for arguments and
result types.

Cheers,

- Alf (grumbling)

PS: Of course, an even more missing language feature is some sort of module
support. The administrative overhead of using libraries in C++, specifying
header and library search paths, binary names etc., is O(n^2) where n is the
number of libraries that are being developed within a project. That's silly.

Hi Alf

I can't understand what do you mean, Please throw the light
by an example.
Also, I definitely sure, you know the best place to discuss missing/
new/defect
feature is comp.std.c++.

AFAIK, There is some proposal for adding Module by Daveed Vandevoorde
in C++ standard committee. Of course it will be for TR2.

Regards,
-- Saeed Amrollahi

standard
 
A

Alf P. Steinbach

* Saeed Amrollahi:
Hi Alf

I can't understand what do you mean, Please throw the light
by an example.

struct Foo
{
typedef Foo Outer;
enum E {};

struct Bar
{
Outer* F( E ) const;
};
};

// Outer* Foo::Bar::F( E ) const { return 0; } -- Nah, but E is OK.
Foo* Foo::Bar::F( E ) const { return 0; // -- Different, OK.

int main()
{}

Also, I definitely sure, you know the best place to discuss missing/
new/defect
feature is comp.std.c++.

I'm just letting out steam.

There's no chance of any new feature in C++0x.

Nor, I think, in C++0x's successor, if any, which IMHO will be the last C++
standard.

AFAIK, There is some proposal for adding Module by Daveed Vandevoorde
in C++ standard committee. Of course it will be for TR2.

I'm not sure. There's always the 'export' issue standing in the way of anything
module-like. I think we'd need ABI standardization along with modules.


Cheers,

- Alf
 
A

Alf P. Steinbach

* Saeed Amrollahi:
Hi Alf

I can't understand what do you mean, Please throw the light
by an example.

Here's a better (worse) example than the fictiuous one I presented else-thread:


class TextEdit
{
protected:
class ApiWindowFactory
{
public:
typedef api::windowStyle::InsetElement InsetElement;

virtual InsetElement::Enum insetElements() const;
};
};


With inline code the definition of that routine is clean, but with a separate
definition in an implementation file ...


TextEdit::ApiWindowFactory::InsetElement::Enum
TextEdit::ApiWindowFactory::insetElements() const
{
...
}


.... just the routine head, a routine with no arguments, is an ungrokkable 101
character line, with extreme redundancy.

Utterly disgusting!


Cheers,

- Alf
 
M

Michael Doubez

I think it's a language defect, or at least an inconsistency, that a definition
of F generally can't use the same type names as the earlier declaration of F.

The source of this problem is that by current rules the compiler evaluates the
routine result type declaration before knowing which routine it's compiling: the
result type, as opposed to argument types, is not evaluated in the routine's
declaration context.

It would IMHO be nice with consistent rules, the same rules, for arguments and
result types.

But then, how would you address the problem of:

class Outer { ...} ;

struct Foo
{
Outer* bla();

typedef Foo Outer;
enum E {};

struct Bar
{
Outer* F( E ) const;
};
};

// Outer must be external outer
Outer* Foo::bla();

// Outer must be Foo::Outer
Outer* Foo::Bar::F( E ) const { return 0; }

int main()
{}

You would not be able to specify Foo::bla because then, it would
believe it to be
Foo::Outer* Foo::bla().
 
A

Alf P. Steinbach

* Michael Doubez:
But then, how would you address the problem of:

class Outer { ...} ;

struct Foo
{
Outer* bla();

typedef Foo Outer;

Shouldn't do that for portable code (see below)... ;-)
enum E {};

struct Bar
{
Outer* F( E ) const;
};
};

// Outer must be external outer
Outer* Foo::bla();

// Outer must be Foo::Outer
Outer* Foo::Bar::F( E ) const { return 0; }

int main()
{}

You would not be able to specify Foo::bla because then, it would
believe it to be
Foo::Outer* Foo::bla().

I'm saying ideally one should have the same rules for result type as for arguments.

Hence there's no problem for result type that isn't there already for arguments.

But you're pointing out a real problem for existing rules for argument types.


<code>
class Outer {} ;

struct Foo
{
void bla( Outer* );

typedef Foo Outer;
enum E {};

struct Bar
{
void F( E, Outer* ) const;
};
};

// Outer must be external outer
void Foo::bla( Outer* ) {}

// Outer must be Foo::Outer
void Foo::Bar::F( E, Outer* ) const {}

int main()
{}
</code>


<comeau>
Comeau C/C++ 4.3.10.1 (Oct 6 2008 11:28:09) for ONLINE_EVALUATION_BETA2
Copyright 1988-2008 Comeau Computing. All rights reserved.
MODE:strict errors C++ C++0x_extensions

"ComeauTest.c", line 17: error: declaration is incompatible with
"void Foo::bla(Outer *)" (declared at line 5)
void Foo::bla( Outer* ) {}
^

1 error detected in the compilation of "ComeauTest.c".
</comeau>


<mingw g++>
hm6.cpp:7: error: declaration of `typedef struct Foo Foo::Outer'
hm6.cpp:1: error: changes meaning of `Outer' from `class Outer'
hm6.cpp:17: error: prototype for `void Foo::bla(Foo*)' does not match any in
class `Foo'
hm6.cpp:5: error: candidate is: void Foo::bla(Outer*)
</mingw g++>


<msvc>
hm6.cpp(17) : error C2511: 'void Foo::bla(Foo::Outer *)' : overloaded member
function not found in 'Foo'
hm6.cpp(4) : see declaration of 'Foo'
</msvc>


It's a different problem.

Intuitively argument types should be looked up in the context of the original
declaration, but the problem is that which declaration that is may depend on the
argument types, which is a bit circular. So the problem you point out (for the
existing language rules) can't be solved in general that way. Some qualification
is simply required when one chooses to "overload" a type name.


Cheers,

- Alf
 
B

Balog Pal

Alf P. Steinbach said:
// Outer* Foo::Bar::F( E ) const { return 0; } -- Nah, but E is OK.
Foo* Foo::Bar::F( E ) const { return 0; // -- Different, OK.

int main()
{}



I'm just letting out steam.

There's no chance of any new feature in C++0x.

But C++0x IIRC covers this problem (to some degree), if you use the new
function decl syntax, that paces the return type at tail.

something like
auto Foo::Bar::F( E ) const -> Outer*; // picks Outer in F's context

possibly there are other new ways too.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,780
Messages
2,569,608
Members
45,249
Latest member
KattieCort

Latest Threads

Top