February 02, 2022

On Wednesday, 2 February 2022 at 11:46:47 UTC, bauss wrote:

>

On Wednesday, 2 February 2022 at 10:53:56 UTC, forkit wrote:

>

On Wednesday, 2 February 2022 at 09:27:02 UTC, duser wrote:

>

missing extern(C), it should be:

module test;
import core.stdc.stdio : FILE, fprintf;

extern(C) extern shared FILE* stderr;

extern(C) int main(string[] args)
{
	fprintf(stderr, "Test\n",);
	return 0;
}

pls.. not more 'extern's ... I'm seeing 'extern' everywhere now...

..I'm gunna puke if I see another one.

and no, that doesn't work either :-(

extern(C) should imply extern in my book. I'm not sure if it does, but it seems wrong if it doesn't.

Shouldn't extern imply extern(D) for D?
In C, extern implies extern "C"
In C++, extern implies extern "C++"

Why different behaviour for D?

February 02, 2022

On Wednesday, 2 February 2022 at 07:33:58 UTC, Basile B. wrote:

>
else version (CRuntime_Microsoft)
{
    ///
    shared FILE* stdin;  // = &__iob_func()[0];
    ///
    shared FILE* stdout; // = &__iob_func()[1];
    ///
    shared FILE* stderr; // = &__iob_func()[2];
}

shouldn't these variable declarations be extern ?

Nope, they are macros in the MSVC headers, no symbols are available. That's why druntime defines them and sets them up at startup, so they aren't available/linked with -betterC.

February 02, 2022

On Wednesday, 2 February 2022 at 11:46:47 UTC, bauss wrote:

>

[..]

extern(C) should imply extern in my book. I'm not sure if it does, but it seems wrong if it doesn't.

No, there is a difference between declaration and definition at the linker level. extern (C|C++|C|Objective-C|Windows|System) sets the mangling of a variable declaration or definition. extern changes a variable definition to a declaration.

Check the following cases:

import core.stdc.stdio : FILE, printf, fprintf;

shared FILE* stderr; // 1.
// extern (D) shared FILE* stderr; // 2.
// extern (C) shared FILE* stderr; // 3.
// extern shared FILE* stderr; // 4.
// extern extern (C) shared FILE* stderr; // 5.


pragma (msg, stderr.mangleof, "\n");

void main()
{
    if (stderr)
        fprintf(stderr, "stderr exists.\n");
    else
        printf("stderr doesn't exist.\n");
}
  1. shared FILE* stderr; -> A global variable stderr declared and defined in the current module with D linkage
    • Compiles and links ok.
    • Prints _D9onlineapp6stderrOPS4core4stdc5stdio8_IO_FILE at compile-time.
    • Prints stderr doesn't exist. at run-time.
  2. extern (D) shared FILE* stderr; -> Same as above - extern (D) is the default linkage.
  3. extern (C) shared FILE* stderr; -> A global variable stderr declared and defined in the current module with C linkage
    • Compiles and links ok.
    • Prints stderr at compile-time.
    • Prints stderr doesn't exist. at run-time.
  4. extern shared FILE* stderr; -> A global variable stderr declared but not defined in the current module with D linkage. It has to be defined in another module (library)
    • Compiles ok, but fails to link.
    • Prints _D9onlineapp6stderrOPS4core4stdc5stdio8_IO_FILE at compile-time.
    • Doesn't run
  5. extern extern (C) shared FILE* stderr; -> A global variable stderr declared but not defined in the current module with C linkage. It has to be defined in another module (library)
    • Compiles and links ok (the compiler/linker driver automatically links libc).
    • Prints stderr at compile-time.
    • Prints stderr exists. at run-time.
February 02, 2022

On Wednesday, 2 February 2022 at 12:17:01 UTC, kinke wrote:

>

On Wednesday, 2 February 2022 at 07:33:58 UTC, Basile B. wrote:

>
else version (CRuntime_Microsoft)
{
    ///
    shared FILE* stdin;  // = &__iob_func()[0];
    ///
    shared FILE* stdout; // = &__iob_func()[1];
    ///
    shared FILE* stderr; // = &__iob_func()[2];
}

shouldn't these variable declarations be extern ?

Nope, they are macros in the MSVC headers, no symbols are available. That's why druntime defines them and sets them up at startup, so they aren't available/linked with -betterC.

Thank you very much, do you know which lib should be linked and why it all works in dmd-2.091.0?

February 02, 2022

On 2/2/22 8:16 AM, Abby wrote:

>

On Wednesday, 2 February 2022 at 12:17:01 UTC, kinke wrote:

>

On Wednesday, 2 February 2022 at 07:33:58 UTC, Basile B. wrote:

>
else version (CRuntime_Microsoft)
{
    ///
    shared FILE* stdin;  // = &__iob_func()[0];
    ///
    shared FILE* stdout; // = &__iob_func()[1];
    ///
    shared FILE* stderr; // = &__iob_func()[2];
}

shouldn't these variable declarations be extern ?

Nope, they are macros in the MSVC headers, no symbols are available. That's why druntime defines them and sets them up at startup, so they aren't available/linked with -betterC.

Thank you very much, do you know which lib should be linked and why it all works in dmd-2.091.0?

Well, looking at the blame for that file, those lines have been there for 10 years, so that isn't the reason for the change.

-Steve

February 02, 2022

On 2/2/22 7:17 AM, kinke wrote:

>

On Wednesday, 2 February 2022 at 07:33:58 UTC, Basile B. wrote:

>
else version (CRuntime_Microsoft)
{
    ///
    shared FILE* stdin;  // = &__iob_func()[0];
    ///
    shared FILE* stdout; // = &__iob_func()[1];
    ///
    shared FILE* stderr; // = &__iob_func()[2];
}

shouldn't these variable declarations be extern ?

Nope, they are macros in the MSVC headers, no symbols are available. That's why druntime defines them and sets them up at startup, so they aren't available/linked with -betterC.

I investigated the history of where these are set (in rt/msvc.d), and it's fascinating.

I'm not sure why it works on 2.091, though, this setup has existed since at least 2015, and probably before. See this PR: https://github.com/dlang/druntime/pull/1360

It was changed from a c file to a d file in October 2020 (see https://github.com/dlang/druntime/pull/3223), maybe that has something to do with it? Though it still shouldn't be running the init_msvc function in -betterC, even in 2.091 (which was released before this change). I tend to believe that maybe the OP is mistaken that it works, or there was a latent bug that was still running some of druntime that has been fixed.

-Steve

February 02, 2022

On Wednesday, 2 February 2022 at 14:38:49 UTC, Steven Schveighoffer wrote:

>

I tend to believe that maybe the OP is mistaken that it works, or there was a latent bug that was still running some of druntime that has been fixed.

Maybe 2.091 was when dub still defaulted to OMF using the DigitalMars runtime, and it just seems to work since it's not using the Windows runtime.

February 02, 2022
On Wednesday, 2 February 2022 at 14:38:49 UTC, Steven Schveighoffer wrote:
>
> I'm not sure why it works on 2.091, though, this setup has existed since at least 2015, and probably before. See this PR: https://github.com/dlang/druntime/pull/1360
>

but it doesn't work on 2.091 ??

how this has escaped the testing process ..is..well..kinda disturbing.

This code below, will not compile using these parameters:

-m64 -betterC

but WILL using

-m32 -betterC

// ---

module test;

import core.stdc.stdio;

extern (C):

int main(int argc,char** argv)
{
    fprintf(stderr, "grr!\n");

    return 0;
}

// -----
February 02, 2022
On Wednesday, 2 February 2022 at 18:51:04 UTC, forkit wrote:
>
> This code below, will not compile using these parameters:
>
> -m64 -betterC
>
> but WILL using
>
> -m32 -betterC
>

.. I mean specifically on Windows of course.

It's fine on linux.
February 02, 2022
On Wednesday, 2 February 2022 at 18:57:21 UTC, forkit wrote:
>

if only godbolt supported D on it's MSVC compilers :-(

https://www.godbolt.ms/