https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122954
--- Comment #5 from Jonathan Wakely <redi at gcc dot gnu.org> --- (In reply to David Binderman from comment #3) > (In reply to Jose E. Marchesi from comment #2) > > - I am keeping the code that triggers the performance problem, because the > > ctx argument is conceptually intended to be copied in a stack fashion. > > As long as you don't mind 150+ places in the code where your customers > will be paying a run time cost to maintain the conceptual intention It depends. If the calls are inlined, any copying might be removed completely. If the calls aren't inline, the function might perform faster because it has its own copy of the data and doesn't need an indirect access through a reference. And some functions really do need their own copy because they modify the LOW_CTX_T before passing it to their callees. > and you don't mind ignoring C++ standard practice, then that's fine. On that subject, these are all completely redundant: typedef struct MODES_T MODES_T; typedef struct NODE_T NODE_T; typedef struct MODE_CACHE_T MODE_CACHE_T; typedef struct MOID_T MOID_T; typedef struct GINFO_T GINFO_T; typedef struct KEYWORD_T KEYWORD_T; typedef struct LINE_T LINE_T; typedef struct NODE_INFO_T NODE_INFO_T; typedef struct PACK_T PACK_T; typedef struct SOID_T SOID_T; typedef struct TABLE_T TABLE_T; typedef struct TAG_T TAG_T; typedef struct TOKEN_T TOKEN_T; typedef struct ORIGIN_T ORIGIN_T; typedef struct POSTULATE_T POSTULATE_T; typedef struct OPTIONS_T OPTIONS_T; typedef struct PARSER_T PARSER_T; typedef struct MODULE_T MODULE_T; typedef struct EXTRACT_T EXTRACT_T; typedef struct MOIF_T MOIF_T; typedef struct A68_T A68_T; typedef struct LOW_CTX_T LOW_CTX_T; In C++ you can always refer to a struct (or class or union) by its tag name without the 'struct' keyword. And these could be constexpr variables initialized with nullptr: #define NO_A68_REF ((A68_REF *) 0) #define NO_ARRAY ((A68_ARRAY *) 0) #define NO_BOOK ((BOOK_T *) 0) #define NO_BOOL ((bool *) 0) #define NO_BYTE ((BYTE_T *) 0) #define NO_CONSTANT ((void *) 0) #define NO_DEC ((DEC_T *) 0) #define NO_EDLIN ((EDLIN_T *) 0) #define NO_FILE ((FILE *) 0) #define NO_FORMAT ((A68_FORMAT *) 0) #define NO_GINFO ((GINFO_T *) 0) #define NO_GPROC ((void (*) (NODE_T *)) 0) #define NO_HANDLE ((A68_HANDLE *) 0) #define NO_INT ((int *) 0) #define NO_JMP_BUF ((jmp_buf *) 0) #define NO_KEYWORD ((KEYWORD_T *) 0) #define NO_NINFO ((NODE_INFO_T *) 0) #define NO_NOTE ((void (*) (NODE_T *)) 0) #define NO_OPTION_LIST ((OPTION_LIST_T *) 0) #define NO_PACK ((PACK_T *) 0) #define NO_PPROC ((PROP_T (*) (NODE_T *)) 0) #define NO_PROCEDURE ((A68_PROCEDURE *) 0) #define NO_REAL ((REAL_T *) 0) #define NO_REFINEMENT ((REFINEMENT_T *) 0) #define NO_REGMATCH ((regmatch_t *) 0) #define NO_SCOPE ((SCOPE_T *) 0) #define NO_SOID ((SOID_T *) 0) #define NO_STREAM NO_FILE #define NO_TEXT ((char *) 0) #define NO_TICK ((bool *) 0) #define NO_TOKEN ((TOKEN_T *) 0) #define NO_TUPLE ((A68_TUPLE *) 0) #define NO_VAR (0) e.g. constexpr A68_REF* NO_A68_REF = nullptr; Or they could all (except the last) just be replaced at the point of use by using nullptr directly. Many of them are never even used in the code.
