abstract sealed & literal

  • Thread starter Thread starter Vedo
  • Start date Start date
V

Vedo

ref struct XXX abstract sealed
{
literal int A = 5;
};

The definition above gives me the compiler warning "C4693: a sealed abstract
class cannot have any instance members 'A'". The equivalent definition is
perfectly legal in other CLR languages. For example in C#;

static class XXX
{
const int A = 5;
}

compiles without any error. Is there a way to specify CLR compatible consts
in a static class in C++/CLI?
 
You haven't got the equivalent in C#.
That would be:
public abstract sealed class XXX
{
}
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: C#/VB to Python converter
 
And the error message you get in C# is: "an abstract class cannot be sealed
or static".
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: C#/VB to Python converter
 
Hi,

Thank you for your reply. A "ref class XXX abstract sealed" class in C++/CLI
is compiled to ".class abstract sealed XXX" in MSIL which means "static
class XXX" in C#. So in your example you use the same keywords in C#, but
semantically they are different declarations.

Somehow the C++/CLI compiler does not allow me to define CLR constants in a
static class, which is normally allowed in CLR.
 
A 'static class' in C# (new in C# 2005) just means that all members are
forced by the compiler to be static.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: C#/VB to Python converter
 
Yes you're right. And the same concept in C++/CLI is supported through the
"abstract sealed" keyword combination.

For example the two classes below are exactly the same;

// C#
public static class XXX
{
public static int F()
{
return 1;
}
}

// C++/CLI
public ref class XXX abstract sealed
{
public:
static int F()
{
return 1;
}
};

Like the C# compiler, the C++/CLI compiler does not allow any instance
members in an "abstract sealed" (static) class. You are only allowed to
define static members. Now the problem is; in C# you can also define a
static class like;

public static class XXX
{
public const int x = 3;
...
}

but

public ref class XXX abstract sealed
{
public:
literal int x = 3;
....
};

fails with the compiler error "C4693: a sealed abstract class cannot have
any instance members 'x'", which is normally legal in MSIL (and in C# too).

Regards...
 
Vedo said:
ref struct XXX abstract sealed
{
literal int A = 5;
};

The definition above gives me the compiler warning "C4693: a sealed abstract class cannot
have any instance members 'A'". The equivalent definition is perfectly legal in other CLR
languages. For example in C#;

An abstract class *cannot* be sealed in C#, in C++/CLI an abstract sealed class can only
have static members.

Please check the language specifications.

Willy.
 
Is this something you can use instead?

ref class XXX abstract sealed
{
static const int A = 5;
};
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: C#/VB to Python converter
 
I want my code to be CLS compliant, but "static const" fields in C++/CLI are
marked with a special modopt attribute when compiled to MSIL which makes
them accessible only from the C++/CLI environment. I think I need to find an
other solution :) Thank you for your suggestions.

Regards...
 
Hi,

Thank you for your reply. You are right. I cannot have instance members in
an abstract sealed class. But are literals instance members? As far as I
know they are always considered to be part of the defining type. In other
words, they are always static members. The C++/CLI generated MSIL code for a
*non-abstract sealed* class with a literal integer field is;

..class public ... XXX
{
.field public static literal int32 i = int32(0x00000001)
}

As you see it is declared as a static field. But if I declare that literal
field in an abstract sealed class, the compiler gives me an error.
 
Willy Denoyette said:
An abstract class *cannot* be sealed in C#, in C++/CLI an abstract sealed
class can only


A C# class can be marked both sealed and abstract, using the "static class"
syntax. In this case it has more restrictions than a non-sealed abstract
class, such as not being able to inherit from a base class.
have static members.

Please check the language specifications.

Please check the IL, as the original poster has done.

This isn't about the C# language, this is about .NET and a particular valid
..NET construct which is not allowed by the C++/CLI compiler. C# happens to
generate that construct just fine.
 
David Anton said:
Is this something you can use instead?

ref class XXX abstract sealed
{
static const int A = 5;
};

Since you specialize in conversions between .NET languages, you surely are
aware than C# const is C++ literal, C# readonly is C++ initonly, and .NET
has no direct support for C++ const (hence the use of modopt, and totally
broken const-correctness in C++/CLI).

Why don't you put that snippet of C# code provided by the original poster in
your converter, and let us know what C++ you get?

The OP has in fact found a bug, because a literal is not an instance member.
The use of literal causes the compiler to tag the member as static and
literal. I found this to be true when I was dealing with reflection emit,
generating enums and enum-alike value types.
 
Instant C++ currently produces:
private ref class XXX sealed abstract
{
private:
static const int A = 5;
};
As a result of this discussion, we'll review whether the "static const" is
appropriate or whether the non-compilable "literal" is more correct.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: C#/VB to Python converter
 
Ben Voigt said:
A C# class can be marked both sealed and abstract, using the "static class" syntax. In
this case it has more restrictions than a non-sealed abstract class, such as not being
able to inherit from a base class.

True, a C# static class gets the "abstract" & "sealed" attributes when compiled, but my
point was that you could not declare a class as "abstract sealed" in C# ....

abstract sealed class C {

error CS0418: 'C': an abstract class cannot be sealed or static

Please check the IL, as the original poster has done.

This isn't about the C# language, this is about .NET and a particular valid .NET construct
which is not allowed by the C++/CLI compiler. C# happens to generate that construct just
fine.

True, seems like C++/CLI compiler interpretes this:
"A type that is both abstract and sealed should have only static member...."
from the "Ecma-335 Common Language Infrastructure" too strictly.

Willy.
 
We've decided to change the conversion of C# constant fields to the more
current C++/CLI "literal" in Instant C++. Thanks for bringing this to our
attention.

However, our previous conversion to 'static const' fields compiles and
appears to work in a reasonably close way to the C# const - in what way is
"const" not supported or broken? For instance, method-level constants can
only be produced with the "const" keyword in C++/CLI.
--
David Anton
www.tangiblesoftwaresolutions.com
Instant C#: VB to C# converter
Instant VB: C# to VB converter
Instant C++: C#/VB to C++ converter
Instant Python: C#/VB to Python converter
 
David Anton said:
We've decided to change the conversion of C# constant fields to the more
current C++/CLI "literal" in Instant C++. Thanks for bringing this to our
attention.

However, our previous conversion to 'static const' fields compiles and
appears to work in a reasonably close way to the C# const - in what way is
"const" not supported or broken? For instance, method-level constants can
only be produced with the "const" keyword in C++/CLI.

I believe you'll find that literals are compile-time constants which can be
used as the cases of a switch statement, but static const members, on which
const is ignored by non-C++ languages, can't (at least when imported from
another assembly).

C++/CLI const is broken because you can't have const member functions which
can be invoked through a const handle, making const handles totally
infeasible (though supported), making const-correctness impossible.
 
Ben said:
C++/CLI const is broken because you can't have const member functions which
can be invoked through a const handle, making const handles totally
infeasible (though supported), making const-correctness impossible.

I hope some day we'll have const member functions in .NET, in a way
that's supported by C# as well. :-( It's such a major quality control
feature, and it's really a basic one. If you can detect an error at
compile time, it saves hours of debugging. I use const all the time, and
I caught countless errors with it. It's been part of C++ for well over a
decade, I just don't understand how a modern language can miss that. It
should really be a part of the .NET CLR type system, with reflection
support.

Tom
 
Tamas Demjen said:
I hope some day we'll have const member functions in .NET, in a way that's
supported by C# as well. :-( It's such a major quality control feature,
and it's really a basic one. If you can detect an error at compile time,
it saves hours of debugging. I use const all the time, and I caught
countless errors with it. It's been part of C++ for well over a decade, I
just don't understand how a modern language can miss that. It should
really be a part of the .NET CLR type system, with reflection support.

Tom

While that would be really nice, it will never happen, because there's now
so much code written without respecting const-correctness. Perhaps it was
considered too hard to understand. After all, if you are given a const
list, does that mean you can't add and remove and replace items in the list,
or that you also can't modify an item already in the list? A proper
solution to that would require solid support for covariant and contravariant
interfaces (which would also be a very good thing although many of the
target group of programmers C# is designed for probably aren't capable of
understanding subtyping). After all, a const reference to a type is nothing
more than a supertype having only the pure inspection part of the interface.
 
Back
Top