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


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
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) }

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.