https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87760

            Bug ID: 87760
           Summary: Unable to delete overloads of std::memset on arm
           Product: gcc
           Version: 6.3.0
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: c++
          Assignee: unassigned at gcc dot gnu.org
          Reporter: federico.kircheis at gmail dot com
  Target Milestone: ---

Hello,

I know this is technically speaking undefined behavior (not allowed to change
things inside namespace std), and thus not a bug but more a feature request.
Since all version of gcc I've tested (x86 and x64), clang, icc and msvc accept
following code, I think it makes sense to open this bug because it would be
nice for gcc to be more consistent, since it's just gcc on arm rejecting it.

----
#include <cstring>

namespace std{
void* memset(void*, std::size_t count, int ch) = delete;
}

struct foo{ // POD
    int a;
    int* b;
    char c;
};

int main() {
    foo b[10];
    std::memset(&b, 0, sizeof b);
    std::memset(&b, 0u, sizeof b);
}
----

This code on arm64 fails to compile with following error message:

----
<source>:4:7: error: deleted definition of 'void* std::memset(void*,
std::size_t, int)'

 void* memset(void*, std::size_t count, int ch) = delete;

       ^~~~~~

<built-in>: note: previous declaration of 'void* std::memset(void*, int, long
unsigned int)'

Compiler returned: 1
----

As already mentioned, this hack works with different compilers and helps to
avoid common errors like forgetting the right order of parameter of memset, ie
it helps at compile time to spot errors where someone writes `std::memset(&b,
sizeof b, 0);` instead of `std::memset(&b, 0, sizeof b);`.

Since I do not have locally an arm version, I tested it on compiler explorer:
https://godbolt.org/z/aTX9FZ


Also note that removing the overload from the global namespace is not an issue
on arm64, ie

----
#include <cstring>

void* memset(void*, std::size_t count, int ch) = delete;

struct foo{ // POD
    int a;
    int* b;
    char c;
};

int main() {
    foo b[10];
    memset(&b, 0, sizeof b);
    memset(&b, 0u, sizeof b);
}
----

compiles fine (except on arm non x64 because the overload is ambiguous, but
AFAIK there is nothing we can do about it).

Reply via email to