C++17, Macro-Parameter mit :: Verbinden?

Gast #6571534
Lesenswert?

Wie kann ich zwei Macro-Parameter mit :: verbinden damit ein voll 
qualifizierter Name ensteht?

mit _ geht es aber nicht mit ::
godbolt: https://gcc.godbolt.org/z/TvY7YT
1
// wenn ich hier den Unterstrich durch :: ersetze hagelt es Fehlermeldungen
2
#define FULL_MEMBER( Struct, Member ) Struct ## _ ## Member
3

4
struct A
5
{
6
    int b;
7
};
8

9
FULL_MEMBER(A,b) // Preprozessor mach daraus A_b, ich hätte gerne A::b
Gast #6571538
Lesenswert?

Hintergrund:

ich wollte mir für ein Reverse-Engineering Projekt so ein kleines 
Hilfs-Macro für die Analyse schreiben - normalerweise nutze ich keine 
Macros aber hier wäre so was schon eine Arbeitserleichterung, wird auch 
nicht teil irgendwelchen Produktiv-Codes
1
struct MemberInfo
2
{
3
    const char* name;
4
    size_t alignof_;
5
    size_t sizeof_;
6
    size_t offsetof_;
7
};
8

9
#define MEMBER_INFO( Struct, Member ) MemberInfo { #Member, alignof( Struct##::##Member ), sizeof( Struct##::##Member ), offsetof(Struct,Member) }
Gast #6571551
Lesenswert?

so würde es gehen aber das sieht schon sehr verrückt aus
1
#define AlignOf( s, m ) alignof( decltype( ( (s*)0 )->m ) )
2
#define SizeOf( s, m ) sizeof( decltype( ( (s*)0 )->m ) )
3

4
#define MEMBER_INFO( Struct, Member ) Mem_info { #Member, AlignOf( Struct, Member ), SizeOf( Struct, Member ), offsetof(Struct,Member) }
#6571824
Lesenswert?

cppbert schrieb:
> Wie kann ich zwei Macro-Parameter mit :: verbinden damit ein voll
> qualifizierter Name ensteht?
>
> mit _ geht es aber nicht

Hä?

> mit ::

Hä?

> godbolt: https://gcc.godbolt.org/z/TvY7YT
> // wenn ich hier den Unterstrich durch :: ersetze hagelt es
> Fehlermeldungen
> #define FULL_MEMBER( Struct, Member ) Struct ## _ ## Member
> struct A

Ja, denn es handelt sich um den "token pasting operator". Der fügt die 
beiden Operanden zusammen, so dass sie vom Compiler als ein einzelnes 
Wort betrachtet werden. Bei :: darf das aber nicht passieren, denn 
Struct, :: und Member müssen drei separte Tokens bleiben, damit der 
Compiler was damit anfangen kann. Warum verwendest du den Operator 
überhaupt?
Gast #6572109
Lesenswert?

Rolf M. schrieb:
> Warum verwendest du den Operator
> überhaupt?

Macro-Unerfahrenheit

so geht es, Danke
1
#include <cstddef>
2
#include <type_traits>
3

4
struct MemberInfo
5
{
6
    const char* name;
7
    int alignof_;
8
    int sizeof_;
9
    int offsetof_;
10
};
11
#define MEMBER_INFO( Struct, Member ) MemberInfo { #Member, alignof( Struct::Member ), sizeof( Struct::Member ), offsetof(Struct,Member) }
12

13
struct A
14
{
15
    int b;
16
};
17

18
int main()
19
{
20
  constexpr MemberInfo mi = MEMBER_INFO(A, b);
21
  return mi.sizeof_;
22
}
Gast #6573269
Lesenswert?

Alignof funktioniert nur auf einen Typ. Je nach dem was mit dem Wert 
bezweckt werden soll müsste man vermutlich das alignment der struct mit 
dem offset des members verrechnen. Ich denke mal (ohne besonders darüber 
nachgedacht oder nachgesehen zu haben) dass structs automatisch 
mindestens das maximum an alignments der members bekommen, also keine 
32bit-aligned struct ein 64bit-aligned member haben kann. Von daher - 
wozu wäre der Wert gut?
1
#define MEMBER_INFO( Struct, Member ) MemberInfo { #Member, alignof( Struct ), sizeof( Struct :: Member ), offsetof(Struct, Member) }

funktioniert im godbolt mit VS.
Gast #6573445
Lesenswert?

>Alignof funktioniert nur auf einen Typ.

hab mich verwirren lassen weil clang, gcc und intel das ohne Problem 
durchgehen lassen

alignof(decltype(Struct::Member))

sollte dann aber das was ich haben will (mit deiner Korrektur) sein
1
#define MEMBER_INFO( Struct, Member ) MemberInfo { #Member, alignof( decltype(Struct::Member) ), sizeof( Struct::Member ), offsetof(Struct,Member) }

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren