Forum: PC-Programmierung C++17, Macro-Parameter mit :: Verbinden?


von cppbert (Gast)


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

von cppbert (Gast)


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) }

von cppbert (Gast)


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) }

von (Gast)


Lesenswert?

1
#define FULL_MEMBER( Struct, Member ) Struct :: Member

funktioniert nicht?

von Rolf M. (rmagnus)


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?

von cppbert (Gast)


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
}

von cppbert (Gast)


Lesenswert?

so wie oben geht es mit dem clang, gcc und intel - aber nicht mit dem 
VS2017 oder VS2019 - mit dem ich arbeite :/

gcc.godbolt: https://gcc.godbolt.org/z/v1GGE6

von (Gast)


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.

von cppbert (Gast)


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) }

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.