www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - core.stdc and betterC

reply dd886k <devddstuff gmail.com> writes:
Hello!

This is my first time posting, so do feel free to correct me and 
this post.

I started writing in D around Q2 2017 and recently been 
re-writing some of my projects as betterC (entirely!).

I noticed something weird. It started with DMD 2.074.0 and it's 
still an issue for me in DMD 2.079.1 (and any other compiler 
really).

Consider this piece:

```
import core.stdc.stdio;

extern(C) void main() {
	printf("a");
}
```

It compiles and runs absolutely wonderful (OMF, MSCOFF, ELF, 
etc.). No issues.

Now consider this piece:

```
import core.stdc.stdio;

extern(C) void main() {
	putchar('a');
}
```

Oops, `Error 42: Symbol Undefined 
__D4core4stdc5stdio7putcharFNbNiNeiZi`! To my surprise, `putchar` 
is extern'd as D in druntime/src/core/stdc/stdio.d, and I find 
that _really silly_.

Which means `putchar`, during linking, is affected for linking 
every single C runtime out there, and the only reason I can think 
of is to easily integrate it with D in general, which in my 
opinion, is not necessarily needed since the D people (not meant 
as an insult) promotes betterC as a stand-alone option.

On Windows, stdin, stdout, and stderr are affected when using 
-m32mscoff and -m64 (and obviously, LDC) because under 
CRuntime_Microsoft, std* are defined as `shared`.

I'm aware that an easy solution would be defining a version 
(D_betterC) section.

Will I do a Pull Request? Unfortunately no, I fear I'll abandon 
mid-way through. It's easier to advise the forums and let an 
actual professional integrate the fix.

If you have other suggestions, I'm all ears.
Apr 29 2018
next sibling parent dd86k <devddstuff gmail.com> writes:
On Sunday, 29 April 2018 at 14:42:39 UTC, dd886k wrote:
 Hello!
Embarrassingly enough, I just noticed I made a typo to my usual username.
Apr 29 2018
prev sibling next sibling parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 30/04/2018 2:42 AM, dd886k wrote:
 Hello!
 
 This is my first time posting, so do feel free to correct me and this post.
 
 I started writing in D around Q2 2017 and recently been re-writing some 
 of my projects as betterC (entirely!).
 
 I noticed something weird. It started with DMD 2.074.0 and it's still an 
 issue for me in DMD 2.079.1 (and any other compiler really).
 
 Consider this piece:
 
 ```
 import core.stdc.stdio;
 
 extern(C) void main() {
      printf("a");
 }
 ```
 
 It compiles and runs absolutely wonderful (OMF, MSCOFF, ELF, etc.). No 
 issues.
 
 Now consider this piece:
 
 ```
 import core.stdc.stdio;
 
 extern(C) void main() {
      putchar('a');
 }
 ```
 
 Oops, `Error 42: Symbol Undefined 
 __D4core4stdc5stdio7putcharFNbNiNeiZi`! To my surprise, `putchar` is 
 extern'd as D in druntime/src/core/stdc/stdio.d, and I find that _really 
 silly_.
 
 Which means `putchar`, during linking, is affected for linking every 
 single C runtime out there, and the only reason I can think of is to 
 easily integrate it with D in general, which in my opinion, is not 
 necessarily needed since the D people (not meant as an insult) promotes 
 betterC as a stand-alone option.
 
 On Windows, stdin, stdout, and stderr are affected when using -m32mscoff 
 and -m64 (and obviously, LDC) because under CRuntime_Microsoft, std* are 
 defined as `shared`.
 
 I'm aware that an easy solution would be defining a version (D_betterC) 
 section.
 
 Will I do a Pull Request? Unfortunately no, I fear I'll abandon mid-way 
 through. It's easier to advise the forums and let an actual professional 
 integrate the fix.
 
 If you have other suggestions, I'm all ears.
Welcome. I just checked, extern(D) isn't at fault. You actually do want name mangling for wrapper functions like that. Did you only -I the file? If you compile it in normally, it won't error out. Normally its compiled into druntime and hence Phobos. We really should have functions like this be templated (empty brackets) so that it'll work with just -I happily.
Apr 29 2018
parent reply dd86k <devddstuff gmail.com> writes:
On Sunday, 29 April 2018 at 14:55:06 UTC, rikki cattermole wrote:
 I just checked, extern(D) isn't at fault. You actually do want 
 name mangling for wrapper functions like that.
Re-externing what I need as C is wasted productivity, IMO.
 Did you only -I the file? If you compile it in normally, it 
 won't error out. Normally its compiled into druntime and hence 
 Phobos.
Yeah, I am using core.stdc which _is_ from druntime indeed, but the hint here is _stdc_ (and more specifically, _std_).
 We really should have functions like this be templated (empty 
 brackets) so that it'll work with just -I happily.
Really it's simply a betterC-related issue and thus why I proposed the insertion of some version (D_betterC) here and there.
Apr 29 2018
parent reply rikki cattermole <rikki cattermole.co.nz> writes:
On 30/04/2018 3:05 AM, dd86k wrote:
 On Sunday, 29 April 2018 at 14:55:06 UTC, rikki cattermole wrote:
 I just checked, extern(D) isn't at fault. You actually do want name 
 mangling for wrapper functions like that.
Re-externing what I need as C is wasted productivity, IMO.
 Did you only -I the file? If you compile it in normally, it won't 
 error out. Normally its compiled into druntime and hence Phobos.
Yeah, I am using core.stdc which _is_ from druntime indeed, but the hint here is _stdc_ (and more specifically, _std_).
 We really should have functions like this be templated (empty 
 brackets) so that it'll work with just -I happily.
Really it's simply a betterC-related issue and thus why I proposed the insertion of some version (D_betterC) here and there.
This issue has nothing to do with -betterC or extern(D). You can get this same issue without it added if you don't link against phobos/druntime. It also isn't specific to core.stdc.*. Just your usage of it (-I'ing only).
Apr 29 2018
parent dd86k <devddstuff gmail.com> writes:
On Sunday, 29 April 2018 at 15:14:25 UTC, rikki cattermole wrote:
 This issue has nothing to do with -betterC or extern(D).
 You can get this same issue without it added if you don't link 
 against phobos/druntime.
Oh heh I think you're right. It is only an issue when linking and by default it does link the C runtime, so I'll be fine making a source file externing everything myself. Didn't think of that, oops.
Apr 29 2018
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2018-04-29 16:42, dd886k wrote:
 Hello!
 
 This is my first time posting, so do feel free to correct me and this post.
 
 I started writing in D around Q2 2017 and recently been re-writing some 
 of my projects as betterC (entirely!).
 
 I noticed something weird. It started with DMD 2.074.0 and it's still an 
 issue for me in DMD 2.079.1 (and any other compiler really).
 
 Consider this piece:
 
 ```
 import core.stdc.stdio;
 
 extern(C) void main() {
      printf("a");
 }
 ```
 
 It compiles and runs absolutely wonderful (OMF, MSCOFF, ELF, etc.). No 
 issues.
 
 Now consider this piece:
 
 ```
 import core.stdc.stdio;
 
 extern(C) void main() {
      putchar('a');
 }
 ```
 
 Oops, `Error 42: Symbol Undefined 
 __D4core4stdc5stdio7putcharFNbNiNeiZi`! To my surprise, `putchar` is 
 extern'd as D in druntime/src/core/stdc/stdio.d, and I find that _really 
 silly_.
 
 Which means `putchar`, during linking, is affected for linking every 
 single C runtime out there, and the only reason I can think of is to 
 easily integrate it with D in general, which in my opinion, is not 
 necessarily needed since the D people (not meant as an insult) promotes 
 betterC as a stand-alone option.
 
 On Windows, stdin, stdout, and stderr are affected when using -m32mscoff 
 and -m64 (and obviously, LDC) because under CRuntime_Microsoft, std* are 
 defined as `shared`.
 
 I'm aware that an easy solution would be defining a version (D_betterC) 
 section.
 
 Will I do a Pull Request? Unfortunately no, I fear I'll abandon mid-way 
 through. It's easier to advise the forums and let an actual professional 
 integrate the fix.
 
 If you have other suggestions, I'm all ears.
Looks like "putchar" is inlined [1]. That means the "putchar" you're referencing is not the one in the C standard library but it's implemented in druntime. That means you need to link with druntime/phobos, it's not enough to link with the C standard library. I don't know why it was done this way. Perhaps it's just a macro on some platforms. [1] https://github.com/dlang/druntime/blob/master/src/core/stdc/stdio.d#L1289 -- /Jacob Carlborg
Apr 29 2018
next sibling parent reply dd86k <devddstuff gmail.com> writes:
On Sunday, 29 April 2018 at 15:40:20 UTC, Jacob Carlborg wrote:
 I don't know why it was done this way. Perhaps it's just a 
 macro on some platforms.
I think it's to better integrate with normal D code (thread safety, which explains the stdin is tagged with shared (TLS)). It's all fine now. I'll type away my own bindings in a separate source file (stdc.d).
Apr 29 2018
parent reply Adam D. Ruppe <destructionator gmail.com> writes:
On Sunday, 29 April 2018 at 15:52:11 UTC, dd86k wrote:
 It's all fine now. I'll type away my own bindings in a separate 
 source file (stdc.d).
You can also just do it in the usage module, for the individual functions you need. I do this a lot for various C libraries (and used to for the Win32 functions before they were included) BTW i haven't tried win32 functions with betterC. we should - and they should generally work, though the struct inits might cause linker errors in some cases. General tip btw: if you do see a linker error about "undefined symbol _Dsomething_init", you can probably just use `= void` when declaring the struct so it is not automatically initialized (so same behavior as C) and then memset it to 0 or whatever you need.
Apr 29 2018
parent reply dd86k <devddstuff gmail.com> writes:
On Sunday, 29 April 2018 at 17:52:15 UTC, Adam D. Ruppe wrote:
 BTW i haven't tried win32 functions with betterC. we should - 
 and they should generally work, though the struct inits might 
 cause linker errors in some cases.
Windows isn't the only one affected. Under CRuntime_Glibc (usually for Linux), std* and all are defined just like in CRuntime_Microsoft, which still make them unusable in a -betterC(-only) context. Or maybe I'm the only special guy who makes my projects betterC as a whole.
 General tip btw: if you do see a linker error about "undefined 
 symbol _Dsomething_init", you can probably just use `= void` 
 when declaring the struct so it is not automatically 
 initialized (so same behavior as C) and then memset it to 0 or 
 whatever you need.
Bless you! That was the last thing I needed to set for `_iob` (which in the Microsoft headers is set to _IOB_ENTRIES (20) and not _NFILE (512) (for FILE[*])), because I did cloned the Phobos repo and did modifications of my own, for my projects.
Apr 30 2018
next sibling parent dd86k <devddstuff gmail.com> writes:
On Monday, 30 April 2018 at 21:51:13 UTC, dd86k wrote:
 Bless you! That was the last thing I needed to set for `_iob` 
 (which in the Microsoft headers is set to _IOB_ENTRIES (20) and 
 not _NFILE (512) (for FILE[*])), because I did cloned the 
 Phobos repo and did modifications of my own, for my projects.
Oh huh, talked too fast. Still having access violations on x86mscoff.
Apr 30 2018
prev sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
Please file all betterC issues with bugzilla and tag them with the 
'betterC' keyword. We want to get them all fixed, and this makes it easy 
to find them!
Apr 30 2018
parent reply dd86k <devddstuff gmail.com> writes:
On Tuesday, 1 May 2018 at 00:34:55 UTC, Walter Bright wrote:
 Please file all betterC issues with bugzilla and tag them with 
 the 'betterC' keyword. We want to get them all fixed, and this 
 makes it easy to find them!
Hello Walter, I hope my first report[1] is properly done before I make other ones. [1] https://issues.dlang.org/show_bug.cgi?id=18816
May 01 2018
parent Walter Bright <newshound2 digitalmars.com> writes:
On 5/1/2018 3:42 PM, dd86k wrote:
 I hope my first report[1] is properly done before I make other ones.

 [1] https://issues.dlang.org/show_bug.cgi?id=18816
Yes, it's good, thanks!
May 02 2018
prev sibling next sibling parent Kagamin <spam here.lot> writes:
On Sunday, 29 April 2018 at 15:40:20 UTC, Jacob Carlborg wrote:
 I don't know why it was done this way. Perhaps it's just a 
 macro on some platforms.
At least ms, glibc and freebsd provide it as a function.
Apr 29 2018
prev sibling next sibling parent reply Walter Bright <newshound2 digitalmars.com> writes:
On 4/29/2018 8:40 AM, Jacob Carlborg wrote:
 Looks like "putchar" is inlined [1]. That means the "putchar" you're
 referencing is not the one in the C standard library but it's
 implemented in druntime. That means you need to link with
 druntime/phobos, it's not enough to link with the C standard library.

 I don't know why it was done this way. Perhaps it's just a macro on some
 platforms.

 [1]
 https://github.com/dlang/druntime/blob/master/src/core/stdc/stdio.d#L1289
It is a macro on some platforms, and that's why it was done that way in core.stdc.stdio. These days, however, it is better to replace such macros with a template. That way it will not be necessary to link with druntime.
Apr 29 2018
parent Jacob Carlborg <doob me.com> writes:
On 2018-04-30 00:52, Walter Bright wrote:

 It is a macro on some platforms, and that's why it was done that way in 
 core.stdc.stdio. 
That makes sense.
 These days, however, it is better to replace such 
 macros with a template. That way it will not be necessary to link with 
 druntime.
That's a good idea. -- /Jacob Carlborg
Apr 30 2018
prev sibling parent Patrick Schluter <Patrick.Schluter bbox.fr> writes:
On Sunday, 29 April 2018 at 15:40:20 UTC, Jacob Carlborg wrote:
 On 2018-04-29 16:42, dd886k wrote:
 [...]
Looks like "putchar" is inlined [1]. That means the "putchar" you're referencing is not the one in the C standard library but it's implemented in druntime. That means you need to link with druntime/phobos, it's not enough to link with the C standard library. I don't know why it was done this way. Perhaps it's just a macro on some platforms. [1] https://github.com/dlang/druntime/blob/master/src/core/stdc/stdio.d#L1289
Yes, putchar is often implemented as a the macro #define putchar(x) putc(x, stdout)
Apr 29 2018