digitalmars.D.learn - Function Parameters without Names?
- Vijay Nayar (27/27) Feb 19 2022 I encountered an odd bug in a project of mine which is
- =?UTF-8?Q?Ali_=c3=87ehreli?= (14/19) Feb 19 2022 This is common in C++ as well. You have to have a parameter because an
- Salih Dincer (43/46) Feb 19 2022 The problem was about
- =?UTF-8?Q?Ali_=c3=87ehreli?= (35/41) Feb 20 2022 I am not sure whether you are asking a question so apologies if I am
- Stanislav Blinov (8/9) Feb 20 2022 1) `extern(C) void* malloc(size_t);`
- Steven Schveighoffer (4/6) Mar 01 2022 Yes, `_param_0`, `_param_1`, etc.
I encountered an odd bug in a project of mine which is illustrated in the example below: ```d class Thing { int val; this(int) { this.val = val; } } void main() { auto t = new Thing(3); assert(t.val != 3); } ``` The problem is that the parameter of the constructor actually has no name at all. Thus, the statement `this.val = val` simply sets the member variable to its own value, thus it stays the same as `int.init`. According to the [specification](https://dlang.org/spec/function.html), this is permissible via the following grammar rules: `FuncDeclaration` => `FuncDeclarator` => `FuncDeclaratorSuffix` => `Parameters` => `ParameterList` => `Parameter` => `Declarator` => `ParameterAttributes_opt Type`. What is the main motivator to allow parameters with no names? Do they get an automatic implied name like `_` or something?
Feb 19 2022
On 2/19/22 15:37, Vijay Nayar wrote:The problem is that the parameter of the constructor actually has no name at all. Thus, the statement `this.val = val` simply sets the member variable to its own valueWow! I've never come accross that one before. :)What is the main motivator to allow parameters with no names?This is common in C++ as well. You have to have a parameter because an interface requires it but you don't really have any use for that parameter. If you name it, then there may be "unused variable" warning. So, it is common to comment out the parameter name so that it is instructive to people who look at the code: void foo(int /* length */) { // ... }Do they get an automatic implied name like `_` or something?The function is compiled to take the specified type of a parameter but it is simply not used. (Names are only for source code so it doesn't matter.) Ali
Feb 19 2022
On Saturday, 19 February 2022 at 23:37:01 UTC, Vijay Nayar wrote:What is the main motivator to allow parameters with no names? Do they get an automatic implied name like `_` or something?The problem was about [here](https://dlang.org/spec/class.html#constructors), it should not be type inference: https://dlang.org/spec/function.html#function-attribute-inference Do you think so? But it works when you open inactive codes and convert this(int) to this(T)! The program below throws an error about ```_param_0``` when compiling because the inferred type is not int. ```d import std.conv; class Foo { int i; // v=== type of inferred this(int)//(T i) { this.i = i;//.to!int; } string test() { return i.to!string; } } void main() { long bar = 42; auto foo = new Foo(bar); assert(foo.test == "42"); /* Error: constructor `source.Foo.this(int _param_0)` is not callable using argument types `(long)` cannot pass argument `bar` of type `long` to parameter `int _param_0` */ } ``` The following doesn't work in a function outside the class: ```d TYPE foo(TYPE) { return 42; } ``` The compiler gives the following error: ```undefined identifier TYPE``` SDB 79
Feb 19 2022
On 2/19/22 22:09, Salih Dincer wrote:The following doesn't work in a function outside the class: ```d TYPE foo(TYPE) { return 42; } ``` The compiler gives the following error: ```undefined identifier TYPE```I am not sure whether you are asking a question so apologies if I am stating the obvious. For (TYPE) to be a template parameter list, there must be the function parameter list as well: TYPE foo(TYPE)() { return 42; } <aside> By the way, the fact that we can return the "int" 42 even when TYPE is e.g. 'short' is thanks to "value range propagation". The compilr sees that the manifest constant 42 fits in a short and compiles the code without complaint. On the other hand, the following modification does not compile: TYPE foo(TYPE)() { int r = 42; return r; // <-- Compilation ERROR // Error: cannot implicitly convert expression `r` of type `int` to `short` } void main() { foo!short(); } </aside> Getting back to the main topic, you may or may not need the function parameter list for a member function: struct S(TYPE) { // This is not a template but a function // with the parameter name not omitted. // (TYPE is already known at this point.) TYPE foo(TYPE) { return 42; } // This is a member function template TYPE bar(TYPE2)() { // ... } } Ali
Feb 20 2022
On Saturday, 19 February 2022 at 23:37:01 UTC, Vijay Nayar wrote:What is the main motivator to allow parameters with no names?1) `extern(C) void* malloc(size_t);` No need for parameter name at all as that is only a declaration. You don't have an implementation thus don't need a name for the parameter. 2) As Ali says, unused parameters (i.e. in template specializations, virtual function overrides, dummy parameters for overload resolution purposes, etc.)
Feb 20 2022
On 2/19/22 6:37 PM, Vijay Nayar wrote:Do they get an automatic implied name like `_` or something?Yes, `_param_0`, `_param_1`, etc. Don't depend on this though, I think it's an implementation detail. -Steve
Mar 01 2022