On Thu, 2023-02-09 at 15:04 +0100, Mark Wielaard wrote:
> Hi Ilya,
> 
> On Wed, 2023-02-08 at 13:22 +0100, Ilya Leoshkevich wrote:
> > If I build:
> > 
> > const char *const apba__ __asm ("argp_program_bug_address") \
> > __attribute__ ((used)) = "foobarbaz";
> > 
> > with C and C++, the difference is going to be:
> > 
> > @@ -1,6 +1,5 @@
> >         .file   "1.c"
> >         .text
> > -       .globl  argp_program_bug_address
> >         .section        .rodata.str1.1,"aMS",@progbits,1
> >  .LC0:
> >         .string "foobarbaz"
> > 
> > This must have to do with C and C++ standards treating const
> > differently [1]. The solution is to add extern:
> > 
> > --- a/lib/printversion.h
> > +++ b/lib/printversion.h
> > @@ -44,6 +44,7 @@ void print_version (FILE *stream, struct
> > argp_state
> > *state);
> >    void (*const apvh) (FILE *, struct argp_state *) \
> >     __asm ("argp_program_version_hook")
> >  #define ARGP_PROGRAM_BUG_ADDRESS_DEF \
> > +  extern const char *const apba__; \
> >    const char *const apba__ __asm ("argp_program_bug_address") \
> >    __attribute__ ((used))
> > 
> > I can include this in v2 if it works for you.
> > 
> > [1]
> > https://stackoverflow.com/questions/8908071/const-correctness-in-c-vs-c
> 
> O nice, that explains it. But then in that case I don't think you
> need
> the __attribute__ ((used)) anymore.
> 
> Also as a nitpick the multiline define could be just a single line if
> you declare the extern on its own in printversion.h.
> 
> And it would be nice to also cleanup apvh/argp_program_version_hook
> so
> it too works with c++, so we can remove the hack in debuginfod.cxx.
> 
> Does the following work for you?
> 
> diff --git a/lib/printversion.h b/lib/printversion.h
> index a9e059ff..bc9ca7ae 100644
> --- a/lib/printversion.h
> +++ b/lib/printversion.h
> @@ -40,9 +40,11 @@ void print_version (FILE *stream, struct
> argp_state *state);
>     variables as non-const (which is correct in general).  But we can
>     do better, it is not going to change.  So we want to move them
> into
>     the .rodata section.  Define macros to do the trick.  */
> +extern void (*const apvh) (FILE *, struct argp_state *);
>  #define ARGP_PROGRAM_VERSION_HOOK_DEF \
>    void (*const apvh) (FILE *, struct argp_state *) \
>     __asm ("argp_program_version_hook")
> +extern const char *const apba__;
>  #define ARGP_PROGRAM_BUG_ADDRESS_DEF \
>    const char *const apba__ __asm ("argp_program_bug_address")
>  
> diff --git a/debuginfod/debuginfod.cxx b/debuginfod/debuginfod.cxx
> index 4271acf4..99b1f2b9 100644
> --- a/debuginfod/debuginfod.cxx
> +++ b/debuginfod/debuginfod.cxx
> @@ -348,7 +348,7 @@ static const char DEBUGINFOD_SQLITE_CLEANUP_DDL[]
> =
>  
>  
>  /* Name and version of program.  */
> -/* ARGP_PROGRAM_VERSION_HOOK_DEF = print_version; */ // not this
> simple for C++
> +ARGP_PROGRAM_VERSION_HOOK_DEF = print_version;
>  
>  /* Bug report address.  */
>  ARGP_PROGRAM_BUG_ADDRESS_DEF = PACKAGE_BUGREPORT;
> @@ -4171,7 +4171,6 @@ main (int argc, char *argv[])
>  
>    /* Parse and process arguments.  */
>    int remaining;
> -  argp_program_version_hook = print_version; // this works
>    (void) argp_parse (&argp, argc, argv, ARGP_IN_ORDER, &remaining,
> NULL);
>    if (remaining != argc)
>        error (EXIT_FAILURE, 0,
> 
> Thanks,
> 
> Mark

This works for me, I will add this to v3. Thanks!

Reply via email to