Re: ImportC: Should this compile?
On Sunday, 19 December 2021 at 02:57:35 UTC, Mike Parker wrote: On Saturday, 18 December 2021 at 22:31:38 UTC, bachmeier wrote: I've been trying to get the stb header library to compile. There's a single remaining failure: ``` typedef struct { unsigned char c[4]; } stb_easy_font_color; stb_easy_font_color c = { 255,255,255,255 }; // use structure copying to avoid needing depending on memcpy() ``` LDC returns ``` stb_easy_font.c(892): Error: 3 extra initializer(s) for `struct __tag21` ``` Is this a bug in ImportC or is it correct that it doesn't compile? What's the best way to fix it while keeping the same behavior and performance? Unless C11 has changed the rules about nested initializers, that should compile. You might try explicit nesting: ```d stb_easy_font_color c = { {255,255,255,255} }; ``` And please file an issue if there isn't one already. (I don't know what struct __tag21 is. It's not anywhere in the source. Assuming that's just a bad error message.) A "tag" is the name of a struct or union, which follows the keyword: ```c struct Foo {}; ``` Here, `Foo` is the tag. Instances of the struct must be declared as `struct Foo`. Think of it like this: `int` is required in declarations of instances of type `int`, so `struct` is required in declarations of type `struct`; the "tag" specifies which struct type, hence `struct Foo x`. `typedef` introduces an alias: ```c typedef struct Bar {} Bar; ``` So `Bar` is now an alias for `struct Bar`, and instances can be declared as `Bar x`. Your example is like this: ```c typedef struct {} stb_easy_font_color; ``` No tag is specified, so the compiler must generate one. In your case, it's `__tag21` and `stb_easy_font_color` is an alias for `struct __tag21`. And yes, using the generated tag in the error message is not at all helpful without the alias. Please file an issue on this, too. Thanks - issues created: [Issue 1](https://issues.dlang.org/show_bug.cgi?id=22610) [Issue 2](https://issues.dlang.org/show_bug.cgi?id=22611)
Re: ImportC: Should this compile?
On Sunday, 19 December 2021 at 03:27:50 UTC, Tejas wrote: Oh wow, the executable gets named `stuff` if that's the first file passed... always thought it would name it the same name as that file which contained `main` If the name of the file with `main` were used, you'd have to have a different default for libraries. Executables and libraries get the name of the first source file passed on the command line by default. This can be overridden with -of.
Re: ImportC: Should this compile?
On Sunday, 19 December 2021 at 02:57:35 UTC, Mike Parker wrote: On Saturday, 18 December 2021 at 22:31:38 UTC, bachmeier wrote: I've been trying to get the stb header library to compile. There's a single remaining failure: ``` typedef struct { unsigned char c[4]; } stb_easy_font_color; stb_easy_font_color c = { 255,255,255,255 }; // use structure copying to avoid needing depending on memcpy() ``` LDC returns ``` stb_easy_font.c(892): Error: 3 extra initializer(s) for `struct __tag21` ``` Is this a bug in ImportC or is it correct that it doesn't compile? What's the best way to fix it while keeping the same behavior and performance? Unless C11 has changed the rules about nested initializers, that should compile. You might try explicit nesting: ```d stb_easy_font_color c = { {255,255,255,255} }; ``` And please file an issue if there isn't one already. (I don't know what struct __tag21 is. It's not anywhere in the source. Assuming that's just a bad error message.) A "tag" is the name of a struct or union, which follows the keyword: ```c struct Foo {}; ``` Here, `Foo` is the tag. Instances of the struct must be declared as `struct Foo`. Think of it like this: `int` is required in declarations of instances of type `int`, so `struct` is required in declarations of type `struct`; the "tag" specifies which struct type, hence `struct Foo x`. `typedef` introduces an alias: ```c typedef struct Bar {} Bar; ``` So `Bar` is now an alias for `struct Bar`, and instances can be declared as `Bar x`. Your example is like this: ```c typedef struct {} stb_easy_font_color; ``` No tag is specified, so the compiler must generate one. In your case, it's `__tag21` and `stb_easy_font_color` is an alias for `struct __tag21`. And yes, using the generated tag in the error message is not at all helpful without the alias. Please file an issue on this, too. Yes, using the nested initializer worked ```c typedef struct { unsigned char c[4]; } stb_easy_font_color; stb_easy_font_color c = { { 255,255,255,255 } }; // use structure copying to avoid needing depending on memcpy() ``` d file: ```d void main(){} ``` command line: ` dmd stuff.c main.d` Oh wow, the executable gets named `stuff` if that's the first file passed... always thought it would name it the same name as that file which contained `main`
Re: ImportC: Should this compile?
On Saturday, 18 December 2021 at 22:31:38 UTC, bachmeier wrote: I've been trying to get the stb header library to compile. There's a single remaining failure: ``` typedef struct { unsigned char c[4]; } stb_easy_font_color; stb_easy_font_color c = { 255,255,255,255 }; // use structure copying to avoid needing depending on memcpy() ``` LDC returns ``` stb_easy_font.c(892): Error: 3 extra initializer(s) for `struct __tag21` ``` Is this a bug in ImportC or is it correct that it doesn't compile? What's the best way to fix it while keeping the same behavior and performance? Unless C11 has changed the rules about nested initializers, that should compile. You might try explicit nesting: ```d stb_easy_font_color c = { {255,255,255,255} }; ``` And please file an issue if there isn't one already. (I don't know what struct __tag21 is. It's not anywhere in the source. Assuming that's just a bad error message.) A "tag" is the name of a struct or union, which follows the keyword: ```c struct Foo {}; ``` Here, `Foo` is the tag. Instances of the struct must be declared as `struct Foo`. Think of it like this: `int` is required in declarations of instances of type `int`, so `struct` is required in declarations of type `struct`; the "tag" specifies which struct type, hence `struct Foo x`. `typedef` introduces an alias: ```c typedef struct Bar {} Bar; ``` So `Bar` is now an alias for `struct Bar`, and instances can be declared as `Bar x`. Your example is like this: ```c typedef struct {} stb_easy_font_color; ``` No tag is specified, so the compiler must generate one. In your case, it's `__tag21` and `stb_easy_font_color` is an alias for `struct __tag21`. And yes, using the generated tag in the error message is not at all helpful without the alias. Please file an issue on this, too.
ImportC: Should this compile?
I've been trying to get the stb header library to compile. There's a single remaining failure: ``` typedef struct { unsigned char c[4]; } stb_easy_font_color; stb_easy_font_color c = { 255,255,255,255 }; // use structure copying to avoid needing depending on memcpy() ``` LDC returns ``` stb_easy_font.c(892): Error: 3 extra initializer(s) for `struct __tag21` ``` Is this a bug in ImportC or is it correct that it doesn't compile? What's the best way to fix it while keeping the same behavior and performance? (I don't know what struct __tag21 is. It's not anywhere in the source. Assuming that's just a bad error message.)
Re: DIP1000: Should this compile
On Thursday, 16 May 2019 at 21:56:52 UTC, Steven Schveighoffer wrote: On 5/16/19 10:21 PM, Max Haughton wrote: https://run.dlang.io/is/cKFsXh Should this compile, or is return scope T* down to the user to not escape (Returning &local directly does not compile) Answer to subject: no. This is a bug. Please file. Not sure what the solution is, because dip1000 makes scope a storage class. So there's no way to tag what the input parameter points at. -Steve The parameter pointer outlives the the &local, i.e. cannot be guaranteed that it doesn't escape, which is sufficient grounds to not allow the assignment. Hopefully, this is a implementation rather specification error (If my understanding of the DIP is correct)
Re: DIP1000: Should this compile
On Thursday, 16 May 2019 at 21:21:51 UTC, Max Haughton wrote: https://run.dlang.io/is/cKFsXh Should this compile, or is return scope T* down to the user to not escape (Returning &local directly does not compile) This is a bug, as can be showed by repeating the call to (*boi).writeln - suddenly the output changes between calls. Filed: https://issues.dlang.org/show_bug.cgi?id=19881 -- Simen
Re: DIP1000: Should this compile
On 5/16/19 10:21 PM, Max Haughton wrote: https://run.dlang.io/is/cKFsXh Should this compile, or is return scope T* down to the user to not escape (Returning &local directly does not compile) Answer to subject: no. This is a bug. Please file. Not sure what the solution is, because dip1000 makes scope a storage class. So there's no way to tag what the input parameter points at. -Steve
DIP1000: Should this compile
https://run.dlang.io/is/cKFsXh Should this compile, or is return scope T* down to the user to not escape (Returning &local directly does not compile)
Re: Should this Compile?
On Tuesday, 3 October 2017 at 23:13:00 UTC, Jonathan M Davis wrote: On Tuesday, October 03, 2017 22:42:35 SamwiseFilmore via Digitalmars-d-learn wrote: On Tuesday, 3 October 2017 at 22:37:17 UTC, SamwiseFilmore wrote: > Am I using the ternary operator correctly here, or is this > an issue with dmd? I'm using dmd v2.076.0. I wrapped the ternary in parentheses, and it compiled. Still, I'm wondering about this behavior. Operator precedence makes it quite clear how the ternary operator is supposed to function, and if you're ever not sure, then put parens around it. https://wiki.dlang.org/Operator_precedence - Jonathan M Davis Thanks, that clears things up. I appreciate it!
Re: Should this Compile?
On Tuesday, October 03, 2017 22:42:35 SamwiseFilmore via Digitalmars-d-learn wrote: > On Tuesday, 3 October 2017 at 22:37:17 UTC, SamwiseFilmore wrote: > > Am I using the ternary operator correctly here, or is this an > > issue with dmd? I'm using dmd v2.076.0. > > I wrapped the ternary in parentheses, and it compiled. Still, I'm > wondering about this behavior. Operator precedence makes it quite clear how the ternary operator is supposed to function, and if you're ever not sure, then put parens around it. Almost every operator has higher precedence than the ternary operator, so aside from simple assignments, you typically have to use parens around it. For some reason, a lot of folks seem to assume that the ternary operator has much higher precedence than it does and get confused by the result, but if you just look at the operator precedence table, it should be pretty obvious why you're seeing what you're seeing: https://wiki.dlang.org/Operator_precedence - Jonathan M Davis
Re: Should this Compile?
On Tue, Oct 03, 2017 at 10:37:17PM +, SamwiseFilmore via Digitalmars-d-learn wrote: [...] > string toString() { > return > this.value.toString() ~ > " of " ~ > this.suit.toString() ~ > this.suit == CardSuit.diamonds ? "" : "\t" ~ > "\tfacing " ~ > this.facing.toString(); > } [...] > This code does not compile with this error message: Error: > incompatible types for ((toString(this.p_value) ~ " of " ~ > toString(this.p_suit)) ~ (this.p_suit)): 'string' and 'CardSuit' > > Am I using the ternary operator correctly here, or is this an issue > with dmd? I'm using dmd v2.076.0. When in doubt, always parenthesize around the ?: operator to prevent ambiguities. I'd write that line as: ... ~ ((this.suit == CardSuit.diamonds) ? "" : "\t") ~ ... It's a few characters more, but will save you headaches from obscure errors caused by unexpected operator precedences. T -- A linguistics professor was lecturing to his class one day. "In English," he said, "A double negative forms a positive. In some languages, though, such as Russian, a double negative is still a negative. However, there is no language wherein a double positive can form a negative." A voice from the back of the room piped up, "Yeah, yeah."
Re: Should this Compile?
On Tuesday, 3 October 2017 at 22:37:17 UTC, SamwiseFilmore wrote: Am I using the ternary operator correctly here, or is this an issue with dmd? I'm using dmd v2.076.0. I wrapped the ternary in parentheses, and it compiled. Still, I'm wondering about this behavior.
Should this Compile?
I've created toString() for a struct (which is a lot more complicated than what I've provided here) that returns a large number of concatenated strings. Here is the example: struct Card { // Flesh out these enums appropriately CardSuit suit; CardValue value; Facing facing; string toString() { return this.value.toString() ~ " of " ~ this.suit.toString() ~ this.suit == CardSuit.diamonds ? "" : "\t" ~ "\tfacing " ~ this.facing.toString(); } } This code does not compile with this error message: Error: incompatible types for ((toString(this.p_value) ~ " of " ~ toString(this.p_suit)) ~ (this.p_suit)): 'string' and 'CardSuit' Am I using the ternary operator correctly here, or is this an issue with dmd? I'm using dmd v2.076.0. This is the ideal way to implement this function, although I could do it other ways.
Re: Should this compile?
On Wednesday, 26 August 2015 at 20:02:35 UTC, Timon Gehr wrote: Another workaround is to order the declarations in the opposite way: import std.stdio; import std.range : chain; auto test(string a,string b) { return chain(a,b); } auto test(string a) { return test(a,"b"); } void main() { writeln(test("a")); } It's definitely a bug if the code is dependent on order of declaration.
Re: Should this compile?
On 08/26/2015 09:55 PM, Timon Gehr wrote: On 08/25/2015 08:29 PM, Vladimir Panteleev wrote: I think this is a bug, but is easily worked around with: auto test(string a) { return .test(a, "b"); } I suspect that the reason the error occurs, is that the auto return type automatically rewrites the function declaration into an eponymous template declaration. ... No true. In fact, doing so manually works around the problem. :o) This compiles and runs: import std.stdio; import std.range : chain; auto test()(string a) { return test(a,"b"); } auto test(string a,string b) { return chain(a,b); } void main() { writeln(test("a")); } Another workaround is to order the declarations in the opposite way: import std.stdio; import std.range : chain; auto test(string a,string b) { return chain(a,b); } auto test(string a) { return test(a,"b"); } void main() { writeln(test("a")); }
Re: Should this compile?
On 08/25/2015 08:29 PM, Vladimir Panteleev wrote: I think this is a bug, but is easily worked around with: auto test(string a) { return .test(a, "b"); } I suspect that the reason the error occurs, is that the auto return type automatically rewrites the function declaration into an eponymous template declaration. ... No true. In fact, doing so manually works around the problem. :o) This compiles and runs: import std.stdio; import std.range : chain; auto test()(string a) { return test(a,"b"); } auto test(string a,string b) { return chain(a,b); } void main() { writeln(test("a")); }
Re: Should this compile?
On Tuesday, 25 August 2015 at 18:29:08 UTC, Vladimir Panteleev wrote: I think this is a bug, but is easily worked around with: auto test(string a) { return .test(a, "b"); } Thanks, this worked. Filled it: https://issues.dlang.org/show_bug.cgi?id=14965
Re: Should this compile?
On Tuesday, 25 August 2015 at 18:19:40 UTC, tchaloupka wrote: import std.stdio; import std.range : chain; auto test(string a) { return test(a, "b"); } auto test(string a, string b) { return chain(a, b); } void main() { writeln(test(a)); } Ends with: Error: forward reference to inferred return type of function call 'test' I know this exact sample is solvable by default parameter but there are cases where it is not possible. What to do then? I think this is a bug, but is easily worked around with: auto test(string a) { return .test(a, "b"); } I suspect that the reason the error occurs, is that the auto return type automatically rewrites the function declaration into an eponymous template declaration. Since this creates a new naming scope, "test" by itself will only match the declaration inside the eponymous template. Forcing the compiler to look on the module level will force it to perform overload resolution.
Should this compile?
import std.stdio; import std.range : chain; auto test(string a) { return test(a, "b"); } auto test(string a, string b) { return chain(a, b); } void main() { writeln(test(a)); } Ends with: Error: forward reference to inferred return type of function call 'test' I know this exact sample is solvable by default parameter but there are cases where it is not possible. What to do then?