Skip to content

Conversation

@WalterBright
Copy link
Member

The existing mechanism is in core.stdc.config, which uses a struct named __c_long. This change enables using an enum instead, which has some advantages:

  • enums are a lot closer to typedefs
  • we can allow implicit conversion of other integers to these special enums
  • linking with druntime will not be required

Later we can do away with core.stdc.config entirely and just predefine these enums in the compiler.

The tests will be when core.stdc.config is redone using enums, which will be the egg (or the chicken?).

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @WalterBright!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

Testing this PR locally

If you don't have a local development environment setup, you can use Digger to test this PR:

dub fetch digger
dub run digger -- build "master + dmd#8152"

@jacob-carlborg
Copy link
Contributor

How will the usage of this look like?

@kinke
Copy link
Contributor

kinke commented Apr 9, 2018

I guess something like

enum __c_long : long;
alias c_long = __c_long;
void foo(c_long c);
void bar() { foo(123); }

I suggest adding special IDs __c_(u)longlong too, as a C++ long long cannot be represented in D for 64-bit Posix targets (excl. macOS after the 2.079 mangling change).

@jacob-carlborg
Copy link
Contributor

enum __c_long : long;
alias c_long = __c_long;

void foo(c_long a){};

void main()
{
   foo(3L);
}

The above results in:

Error: function main.foo (__c_long a) is not callable using argument types (long)

@jacob-carlborg
Copy link
Contributor

jacob-carlborg commented Apr 10, 2018

@WalterBright would you consider trying to get this working instead #7458? That is, adding support for pragma(mangle) to alias declarations.

@WalterBright
Copy link
Member Author

That is, adding support for pragma(mangle) to alias declarations.

It's completely antiethical to the way alias works. Aliases are internally instantly replaced with their aliased type all through the compiler. Enums are not, which is why doing special enums is a very small change.

@jacob-carlborg
Copy link
Contributor

What's the advantage of using an enum instead of a struct?

@jacob-carlborg
Copy link
Contributor

It's completely antiethical to the way alias works. Aliases are internally instantly replaced with their aliased type all through the compiler. Enums are not, which is why doing special enums is a very small change.

That might be the case but it would be very convenient.

@WalterBright
Copy link
Member Author

What's the advantage of using an enum instead of a struct?

  • enums are a lot closer to typedefs
  • we can allow implicit conversion of other integers to these special enums
  • linking with druntime will not be required

@rainers
Copy link
Member

rainers commented Apr 11, 2018

The tests will be when core.stdc.config is redone using enums, which will be the egg (or the chicken?).

You can add the enum declarations into the test file right now. This is currently done for the struct version in cppa.d.

@WalterBright WalterBright force-pushed the c_long branch 2 times, most recently from d581138 to 3daef90 Compare April 12, 2018 01:21
@WalterBright
Copy link
Member Author

Ok I added some tests to cppa.d

Copy link
Contributor

@jacob-carlborg jacob-carlborg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you add a usage test as well that verifies that the implicit conversions work too.

Copy link
Member

@ibuclaw ibuclaw left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing that I don't think is handled here but probably will need to be in druntime are type properties. Wouldn't you need to declare enum members named init, max, min, etc... Unless there is special handling in the compiler that I'm not seeing here.

else if (id == Id.__c_ulong)
t = TYulong;
else if (id == Id.__c_long_double)
t = TYdouble;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I take it that tydouble is correct here, and that there is no long double ty.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a TYdouble_alias, but it is used by the dmc++ front end to do name mangling. The code generator doesn't care - the dmd front end does the name mangling.

@WalterBright WalterBright force-pushed the c_long branch 6 times, most recently from e8f903f to 22f61fc Compare April 12, 2018 07:25
version (CRuntime_Microsoft)
{
struct __c_long_double
version (PULL8152)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the reasoning for the version statement? Will this test be run on a compiler that doesn't contain this change?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't have two global declarations of __c_long, etc.

@WalterBright
Copy link
Member Author

Unless there is special handling in the compiler that I'm not seeing here.

The .init was there, but not .max/.min. I added them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants