Force compilation with an error if a structure member with a specific name exists

Suppose that bad_nameis a restricted identifier, for example, that I do not want to be part of the structure. I am looking for a mechanism to force compilation to fail in this case.

example.h

struct example {
  int okay_name;
  int bad_name; 
}

main.cc

#include "example.h"

int main() {
  example ex;
  // cause compilation to fail here if bad_name is a member of ex

  return 0;
}

There are probably ways to cause a crash at runtime by simulating reflection, but is there a way to do this at compile time?

+4
source share
4 answers

You can define it bad_nameas something causing a compile-time error. For example, nothing:

#define bad_name

gives gcc

error: declaration declares nothing [-fpermissive]

int bad_name;

+4
source

C :

#define bad_name xxx; char static_assertion_bad_name_used[-1];

struct example {
  int okay_name;
  int bad_name;
};

GCC :

main.c:6: error: size of array ‘static_assertion_bad_name_used’ is negative

, , ( ).

, MS Visual Studio , . :

#define bad_name xxx; int static_assertion_bad_name_used : 0;

GCC:

main.c:5: error: zero width for bit-fieldstatic_assertion_bad_name_used

, -, - VS.

, , _ Static_assert, .

+4

:

#include <cstdint>

#define DEFINE_HAS_SIGNATURE(traitsName, funcName, signature)               \
    template <typename U>                                                   \
    class traitsName                                                        \
    {                                                                       \
    private:                                                                \
        template<typename T, T> struct helper;                              \
        template<typename T>                                                \
        static std::uint8_t check(helper<signature, &funcName>*);           \
        template<typename T> static std::uint16_t check(...);               \
    public:                                                                 \
        static                                                              \
        constexpr bool value = sizeof(check<U>(0)) == sizeof(std::uint8_t); \
    }

DEFINE_HAS_SIGNATURE(has_bad_name, T::bad_name, decltype(&T::bad_name));

static_assert ( ++ 11):

static_assert(!has_bad_name<example>::value, "");
+1

Suppose bad_name is a restricted identifier, for example, that I do not want to be part of the structure. I am looking for a mechanism to make compilation fail in this case.

This is not fully portable, but at least in VC ++ and GCC you can mark the identifier as deprecated and, if you want, raise a warning that it gives an error.

0
source

Source: https://habr.com/ru/post/1536536/


All Articles