Skip to content

add const to cppmangle.d#5411

Merged
andralex merged 1 commit intodlang:masterfrom
WalterBright:constCppmangle
Feb 6, 2016
Merged

add const to cppmangle.d#5411
andralex merged 1 commit intodlang:masterfrom
WalterBright:constCppmangle

Conversation

@WalterBright
Copy link
Member

trivial refactor

@yebblies
Copy link
Contributor

yebblies commented Feb 6, 2016

Wouldn't it be nice if string implicitly converted to const(void)*?

@WalterBright
Copy link
Member Author

I believe that feature was removed at one point because of overloading problems.

@yebblies
Copy link
Contributor

yebblies commented Feb 6, 2016

Yet you've never provided an example that has problems if the conversion is enabled.

It was disabled long before the current polysemous string literal semantic, so I wouldn't be surprised if the problem doesn't exist any more.

@WalterBright
Copy link
Member Author

It was a looong time ago, and I don't remember the details or the arguments. I suggest that debate has nothing to do with this PR and should be in a DIP, the n.g. or an ER.

@yebblies
Copy link
Contributor

yebblies commented Feb 6, 2016

You mean like this?

It has to do with this PR because it forces otherwise unnecessary use of .ptr.

@WalterBright
Copy link
Member Author

I'm not mixing up changing the language behavior with refactoring the internals of the compiler.

@yebblies
Copy link
Contributor

yebblies commented Feb 6, 2016

It wouldn't help anyway, since we need to be able to build with 2.067. I'm just still annoyed that it was dismissed for such vague and tenuous reasons.

@ibuclaw
Copy link
Member

ibuclaw commented Feb 6, 2016

Oh, this one again.

You mean like this?

I find myself now still agreeing with my 2 year junior self in that issue. If you're comparing strings, use strncmp.

@andralex
Copy link
Member

andralex commented Feb 6, 2016

The overloading problem is simply that adding one more rule is one more trap for the unwary. Consider:

void fun(const(void)*);
void fun(string);
void gun(string a)
{
    fun(a);
}

Now if through refactoring a changes to const(char)[], the other overload gets called.

@yebblies It's great to demand proper justification of choices in language design. This one is a complete dud. I'll close the issue and please let's not play the game of reopening and re-closing etc. Conversion to const(void)* is lossy: type information is lost, size information is lost. Even the alignment information is lost (sic!). The only way to ever use that pointer is in system code. Now, lossy conversions would have to have a tremendous amount of utility to be implicit. We have a few:

  • real to double, double to float
  • int to float, long to double
  • arrays to void[](and qualified versions)
  • upcasts (including of qualifiers) may also be considered lossy

Now I completely understand how some would find the conversion from string to const(void)* useful enough to deserve a place on that list. That's not demonstrably right or wrong. Walter's and mine design sensibilities are not in sync with those folks', and there is not an awful lot of explanation and justification we could possibly bring to the table.

@andralex
Copy link
Member

andralex commented Feb 6, 2016

Auto-merge toggled on

andralex added a commit that referenced this pull request Feb 6, 2016
@andralex andralex merged commit 7a81fa3 into dlang:master Feb 6, 2016
@WalterBright WalterBright deleted the constCppmangle branch February 6, 2016 22:31
@dnadlinger
Copy link
Contributor

@andralex: Since you chose to respond here instead of on Bugzilla, I'll follow suite: The elephant in the room that you omit from your analysis is that const(char)* is already implicitly convertible to const(void)*. If it was me, I'd totally disallow the implicit string literal conversions in the first place – having to type .ptr is not so bad compared to the language consistency benefits, even in C-heavy code –, so I'm not going to perpetuate that argument. But turning this into a discussion about lossy conversions is putting up quite an obvious strawman. The conversion is already in the language.

@yebblies
Copy link
Contributor

yebblies commented Feb 7, 2016

I'm really starting to doubt that you understand the issue here.

We already have the 'lossy' implicit conversion from string literals to const(char)*. It already exists and is not likely to go away. We also have the standard conversion from const(char)* to const(void)*. The problem is that a long time ago, for long forgotten reasons, a special case was added that prevents these conversions from being chained.

Now if through refactoring a changes to const(char)[], the other overload gets called.

No, it doesn't. const(char)[] does not implicitly convert to const(char)*. Only string literals allow the implicit conversion to pointer types.

Try compiling this and see what happens:

void fun(const(char)*);
void fun(string);
void gun(const(char)[] a)
{
    fun(a);
}

The conversion to const(void)* is treated exactly the same, except that a const(char)* overload will be preferred.

It's great to demand proper justification of choices in language design. This one is a complete dud. I'll close the issue and please let's not play the game of reopening and re-closing etc.

From that example, it really doesn't seem like you understand the proposed change. Maybe we're hitting the limits of text-based communication again? An executive decision should at the very least require that you understand the issue.

@andralex
Copy link
Member

andralex commented Feb 7, 2016

@yebblies I'd forgotten since about your consistency argument, thanks. It had not been forgotten when the decision was taken, only during my rehash here.

The consistency argument is good. It is duly noted. It does not influence the decision. One simple way to look at it is the real exception is the conversion of string literals to const(char)*, which is irregular (generally T[] does not convert to const(T)*). The trick is well understood among the community - string literals are zero-terminated, which makes them compatible with the usual C convention etc. So that's an exception. It does not bind us to being consistent with it.

@klickverbot if we disabled conversion from const(char)* to const(void)* we'd then create a precedent and an argument to disallow all conversions from const(T)* to const(void)*. That would be too much a change.

@dnadlinger
Copy link
Contributor

@andralex: I agree, and didn't suggest that. What I'd do differently when starting with a clean slate is to

disallow the implicit string literal conversions

i.e. the string -> const(char)* part, not the const(char)* -> const(void)* one.

@andralex
Copy link
Member

andralex commented Feb 8, 2016

@klickverbot agreed, prolly a trick too cute for its own good.

@WalterBright
Copy link
Member Author

The special case implicit string literal conversion to const(char)* is there in particular to support calling printf, etc., as is the 0-termination of those literals. It would be ugly and annoying to have to write all those with .ptr. Sure, it's not consistent with the rest of the language. But it's pragmatically worth it, given the goal of easy interoperability with C code. (In most languages, string literals are special in one way or another, again for pragmatic reasons.)

But I don't see such a pragmatic need to support converting to const(void)*, and yes, I read @yebblies' examples in the bugzilla issue he wrote.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants

Comments