Skip to content
This repository was archived by the owner on Oct 12, 2022. It is now read-only.

Add @nogc variants for array utils functions#3583

Merged
RazvanN7 merged 1 commit intodlang:masterfrom
teodutu:nogc-aray-utils
Oct 12, 2021
Merged

Add @nogc variants for array utils functions#3583
RazvanN7 merged 1 commit intodlang:masterfrom
teodutu:nogc-aray-utils

Conversation

@teodutu
Copy link
Copy Markdown
Member

@teodutu teodutu commented Oct 9, 2021

This PR also replaces the error messages in _d_arrayctor with those provided by enforceRawArraysConformableNogc.

The previous error messages in _d_arrayctor were displaying too few details, because the initial enforceRawArraysConformable function could not be used, as it was not @nogc. This decision was described in this PR: #3582.

Also use enforceRawArraysConformableNogc in _d_arrayctor

Signed-off-by: Teodor Dutu <teodor.dutu@gmail.com>
@dlang-bot
Copy link
Copy Markdown
Contributor

Thanks for your pull request and interest in making D better, @teodutu! We are looking forward to reviewing it, and you should be hearing from a maintainer soon.
Please verify that your PR follows this checklist:

  • My PR is fully covered with tests (you can see the coverage diff by visiting the details link of the codecov check)
  • My PR is as minimal as possible (smaller, focused PRs are easier to review than big ones)
  • I have provided a detailed rationale explaining my changes
  • New or modified functions have Ddoc comments (with Params: and Returns:)

Please see CONTRIBUTING.md for more information.


If you have addressed all reviews or aren't sure how to proceed, don't hesitate to ping us with a simple comment.

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 run digger -- build "master + druntime#3583"


alias Type = void function(const char[] action, const size_t elementSize,
const void[] a1, const void[] a2, in bool allowOverlap = false) @nogc pure nothrow;
(cast(Type)&enforceRawArraysConformableNogc)(action, elementSize, a1, a2, false);
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This is a void nothrow pure function. Are we sure that the compiler does not optimize away calls to it?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I've compiled and disassembled the code with optimisations turned on (-release -O -inline -boundscheck=off) and off and enforceRawArraysConformable was performing the function call. However, I've only performed this check on my Linux x64 machine.

Is there a way I can enforce the call to enforceRawArraysConformableNogc regardless of optimisations?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Should be fine.

@RazvanN7 RazvanN7 merged commit 16c836a into dlang:master Oct 12, 2021
const overlappedBytes = bytes - d;

assert(0, errorMessage("Overlapping arrays in %s: %zu byte(s) overlap of %zu",
action, overlappedBytes, bytes));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Wait, how is this @nogc? It's a throw new AssertError(…) when compiling druntime with enabled assertions. If it really was @nogc, then there'd be no need to hack-casting the function type.

Copy link
Copy Markdown
Contributor

@kinke kinke Oct 12, 2021

Choose a reason for hiding this comment

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

Oh, it defaults to throwing a staticError!AssertError, so assert() is @nogc (although the custom assert handler might use it AFAICT). Anyway, the functions can apparently be properly decorated with @nogc.

As DMD ships with release druntime only, the assert(0) boils down to a rather unhelpful invalid-instruction, no msg is displayed. It might make sense to invoke _d_assert_msg manually to make sure the message is actually used.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Oh, it defaults to throwing a staticError!AssertError, so assert() is @nogc (although the custom assert handler might use it AFAICT) Anyway, the functions can apparently be properly decorated with @nogc.

Yes.

there'd be no need to hack-casting the function type

You're right. I added the cast there more for the purpose of clarity than out of an actual need. I should probably remove it.

Anyway, the functions can apparently be properly decorated with @nogc.

They can. I chose not to because @nogc would have been inferred anyway, but I see your point.

As DMD ships with release druntime only, the assert(0) boils down to a rather unhelpful invalid-instruction, no msg is displayed. It might make sense to invoke _d_assert_msg manually to make sure the message is actually used.

I think you're right here. I'm going to change the asserts into _d_assert_msgs

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks!

I chose not to because @nogc would have been inferred anyway, but I see your point.

Attributes are only inferred for templates and auto return types.

{
import core.stdc.stdio : snprintf;
snprintf(&_store[0], _store.sizeof, format, &action[0], args);
return _store;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

This returns the full buffer. You'll probably want to return the actual payload only, using the snprintf return value (see its spec, it might return a number greater than the buffer size if it wasn't sufficiently large).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes, I can do that, too. Also, snprintf returns the number of bytes written, so in this case it cannot return more that _store.sizeof, i.e. 256. It could return a negative value, meaning an output error, but that's besides the point and nearly impossible to happen here.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

See https://www.cplusplus.com/reference/cstdio/snprintf/:

Return Value
The number of characters that would have been written if n had been sufficiently large, not counting the terminating null character.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Also note that you are assuming action is null-terminated (because the format string uses %s and you're passing the pointer only). %.*s is the usual way of preventing this undocumented assumption.

@teodutu teodutu deleted the nogc-aray-utils branch October 13, 2021 17:57
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants