June 06, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mafi Attachments: | On Fri, 05 Jun 2015 20:36:19 +0000, Mafi wrote:
> On Friday, 5 June 2015 at 10:56:36 UTC, ketmar wrote:
>
>
>> p.s. if "auto" is a storage class, the following code should be
>> accepted (while it isn't):
>>
>> int foo () { return 42; }
>>
>> void main () {
>> auto auto i = foo();
>> }
>>
>> as it's logically "an auto-typed var with "auto" storage class".
>
> Here lies your mistake. There is no such thing as "auto"-typed (leaving aside function signatures, which might be special-cased and are different beast altogether). Auto is not a type. auto* or auto[] aren't valied either. Auto is just a storage class, no more, no less. You use it if the grammar needs a storage class but you don't want to give special attributes to the variable (like const or static). To make a declaration with inferred type you need at least one storage class. To make it work with "normal" variables you use "auto".
so either `const auto` should not be accepted, or `auto auto` should be accepted. if `auto` plays a role of "default storage class", the `const auto` should trigger the error about redundant storage specifier. if `auto` can play a role of type placeholder, then `auto auto` should be accepted, as it's clearly the "default storage class with type placeholder".
current situation is inconsistent and that inconsistency must be fixed.
| |||
June 06, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Mafi Attachments: | On Fri, 05 Jun 2015 20:36:19 +0000, Mafi wrote:
> On Friday, 5 June 2015 at 10:56:36 UTC, ketmar wrote:
>
>
>> p.s. if "auto" is a storage class, the following code should be
>> accepted (while it isn't):
>>
>> int foo () { return 42; }
>>
>> void main () {
>> auto auto i = foo();
>> }
>>
>> as it's logically "an auto-typed var with "auto" storage class".
>
> Here lies your mistake. There is no such thing as "auto"-typed (leaving aside function signatures, which might be special-cased and are different beast altogether). Auto is not a type. auto* or auto[] aren't valied either. Auto is just a storage class, no more, no less. You use it if the grammar needs a storage class but you don't want to give special attributes to the variable (like const or static). To make a declaration with inferred type you need at least one storage class. To make it work with "normal" variables you use "auto".
p.s. even more samples: `foreach (auto n; 0..10)`. this doesn't work at all. why? `foreach (immutable n; 0..10)` works perfectly. so `auto` clearly is not a "storage class", as it is forbidden where storage classes are allowed.
| |||
June 06, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Saturday, 6 June 2015 at 06:05:46 UTC, ketmar wrote: > On Fri, 05 Jun 2015 18:35:49 +0000, Marc Schütz wrote: > >> On Friday, 5 June 2015 at 17:50:55 UTC, ketmar wrote: >>> `const int` works, so i can't see why `auto auto` is failing. >> >> Wrong analogy. Try `const const`, and it will fail with the same error >> as `auto auto`: "redundant attribute". > > nope. in `auto auto` one `auto` is storage type, and another `auto` is a > type placeholder. No, as others have explained. > see, `const auto` works, so `auto` can play role of a > type placeholder. so `auto auto` should be accepted, if you insists that > it can play a role of storage class. `const auto` isn't contradictory. It's simply two storage classes, one of which is the default. Besides, there's not much sense in doing experiments with DMD to find out "the true nature" of auto. DMD is clearly inconsistent, as seen from your observation about foreach(). | |||
June 06, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz Attachments: | On Sat, 06 Jun 2015 12:36:09 +0000, Marc Schütz wrote: > `const auto` isn't contradictory. It's simply two storage classes, one of which is the default. but it is! ok, how about `shared auto i = 42;`? what the $#^# `auto` means here? what is that "default storage class" then, and why it doesn't apply here? > Besides, there's not much sense in doing experiments with DMD to find > out "the true nature" of auto. DMD is clearly inconsistent, > as seen from your observation about foreach(). ok, but what i should consult then? specs? but specs clearly allows `const immutable shared auto scope inout __gshared int i = 42;`. yes, specs clearly says that `auto` is a storage class. specs also allowing `auto auto auto auto auto int i = 42;`. what should i check to see what is *really* allowed, why two storage classes allowed with one combination and not allowed with another? | |||
June 06, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Saturday, 6 June 2015 at 15:12:38 UTC, ketmar wrote:
> what should i check to see what is *really* allowed, why two storage
> classes allowed with one combination and not allowed with another?
Well, you can look at the compiler's source...
But I'm sure this is not the answer you wanted ;-)
| |||
June 07, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Marc Schütz Attachments: | On Sat, 06 Jun 2015 18:49:00 +0000, Marc Schütz wrote:
> On Saturday, 6 June 2015 at 15:12:38 UTC, ketmar wrote:
>> what should i check to see what is *really* allowed, why two storage classes allowed with one combination and not allowed with another?
>
> Well, you can look at the compiler's source...
>
> But I'm sure this is not the answer you wanted ;-)
sure. now i'm completely lost. i shouldn't use DMD to find out things, yet i have to use DMD to find out things.
ok, let's be serious. what i'm trying to say is that there should be not only grammar with comments inside it here and there, but the document that explains "what is what", what's compatible with what and so on. the "specs" in the meaning that one can point to it and say: "this is how it is supposed to be. now fix your code". or "now let's fix the compiler."
the specs where no "undefined behavior" words are used, and no "it's left to compiler implementer to decide". (but "look at DMDFE source" is allowed ;-).
| |||
June 07, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ketmar | On Sunday, 7 June 2015 at 05:02:47 UTC, ketmar wrote: > On Sat, 06 Jun 2015 18:49:00 +0000, Marc Schütz wrote: > >> On Saturday, 6 June 2015 at 15:12:38 UTC, ketmar wrote: >>> what should i check to see what is *really* allowed, why two storage >>> classes allowed with one combination and not allowed with another? >> >> Well, you can look at the compiler's source... >> >> But I'm sure this is not the answer you wanted ;-) > > sure. now i'm completely lost. i shouldn't use DMD to find out things, > yet i have to use DMD to find out things. Im my defense, you asked what _is_ really allowed, not what _should_ be allowed... > > ok, let's be serious. what i'm trying to say is that there should be not > only grammar with comments inside it here and there, but the document > that explains "what is what", what's compatible with what and so on. the > "specs" in the meaning that one can point to it and say: "this is how it > is supposed to be. now fix your code". or "now let's fix the compiler." > > the specs where no "undefined behavior" words are used, and no "it's left > to compiler implementer to decide". (but "look at DMDFE source" is > allowed ;-). Brian Schott did a lot of work finding inconsistencies and ambiguities in the grammar, and I believe his DConf talk was partially about it. | |||
June 07, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ketmar | On 06/06/2015 08:06 AM, ketmar wrote:
> On Sat, 06 Jun 2015 00:28:51 +0200, Timon Gehr wrote:
>
>> On 06/05/2015 02:33 PM, ketmar wrote:
>>> i agree, i think it was a keyword used 'cause it was already used in C.
>>> but it's meaning is completely redefined in D.
>>
>> The meaning is exactly the same. It's the default storage class.
>
> then i'll fill a bug about `auto auto` and will reopen it until it's
> fixed.
>
This is valid C:
int main(){
const auto int x=2;
return 0;
}
This is not valid C:
int main(){
auto auto int x=2;
return 0;
}
What is the problem?
| |||
June 07, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to ketmar | On 06/06/2015 08:10 AM, ketmar wrote:
> if `auto` can play a role of type placeholder
There is no such thing as a type placeholder.
| |||
June 07, 2015 Re: Code behaves incorrectly if it is compiled in std.functional | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | On 06/07/15 18:49, Timon Gehr via Digitalmars-d wrote:
> This is valid C:
>
> int main(){
> const auto int x=2;
> return 0;
> }
>
> This is not valid C:
>
> int main(){
> auto auto int x=2;
> return 0;
> }
>
> What is the problem?
The problem is the apparently common misunderstanding that 'auto' is a thing in D. It is not; it's just a grammar hack.
The (very simplified) rule for declarations in C/C++/D is
<storage_class> <type> lhs = rhs
In C, you can omit the /storage_class/ and it then defaults to 'auto'. Obviously, the 'auto' keyword is redundant and nobody actually uses it.
In D, you can omit the /type/ and it's then propagated from the /rhs/ expression. The compiler already knows the type that 'rhs' evaluates to.
But you can not omit both the /type/ and the /storage_class/ as 'lhs=rhs' would be indistinguishable from an assignment. In some contexts for the compiler, but, more importantly, for the human. Hence 'auto lhs = rhs'.
[The exceptions are either because of backward C compatibility
(function args) or no need for such compatibility (foreach)]
Still, 'auto' isn't as bad as 'static', which D redefined to mean
something different than in C/C++, and did this so subtly that
the C version will still compile, giving unexpected results without
even a warning.
artur
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply