Chyba zepuste uClibc na TH - lvm2 i device-mapper

Jakub Bogusz qboosh w pld-linux.org
Pon, 4 Cze 2007, 17:52:55 CEST


On Mon, Jun 04, 2007 at 08:41:35AM +0200, Paweł Sikora wrote:
> Jakub Bogusz pisze:
> > On Mon, Jun 04, 2007 at 07:20:20AM +0200, Paweł Sikora wrote:
> >> On Sunday 03 of June 2007 22:35:43 Jakub Bogusz wrote:
> >>
> >>>     if (likely(_stdio_init != NULL))
> >>>         _stdio_init();
> >>>
> >>> ten warunek jakoś się optymalizuje do true, przez co bezwarunkowo
> >>> wywołuje _stdio_init(),
> >> the address of ???_stdio_init??? will always evaluate as ???true???.
> > 
> > Co tak pisze? Bo nie gcc 4.1.2 ani 4.2.0 przy kompilacji uClibc.
> > -Wall jest w użyciu.
> 
> $ cat t.c
> extern void _stdio_init(void) __attribute__((visibility("hidden")));
> int main()
> {
>          if ( _stdio_init )
>                  _stdio_init();
> }
> 
> $ gcc -Wall t.c -c
> t.c: In function 'main':
> t.c:4: warning: the address of '_stdio_init' will always evaluate as 'true'
> t.c:6: warning: control reaches end of non-void function

Bez weak owszem, ma pełne prawo.
Co ciekawe ostrzeżenie jest tylko przy pominięciu "!= NULL". Oczywiście
warunki usuwa w także z "!= NULL".

> gcc-4.2.0-5.x86_64
> 
> > Bez __attribute__((weak)) dla _stdio_init() by miał do tego prawo (choć
> > też nie zgłasza, optymalizuje po cichu).
> 
> ja tam widze, tylko hidden:
> include/bits/uClibc_stdio.h:
>    extern void _stdio_init(void) attribute_hidden;

W plikach z tymi odwołaniami jest weak:

libc/misc/internals/__uClibc_main.c:
extern void weak_function _stdio_init(void) attribute_hidden;

libc/stdlib/_atexit.c:
extern void weak_function _stdio_term(void) attribute_hidden;

Nawet jeśli ten poprzedni prototyp dołącza wcześniej, to w krótkim kodzie
nie powoduje to pominięcia warunku:

#v+
#include <stdlib.h>

extern void func1(void);
extern void func2(void) __attribute__((visibility("hidden")));

extern void __attribute__((weak)) func1(void);
extern void __attribute__((weak)) func2(void) __attribute__((visibility("hidden")));

# define likely(x)      __builtin_expect((!!(x)),1)

int main()
{
  if(likely(func1 != NULL))
    func1();
  if(likely(func2 != NULL))
    func2();
}
#v-


-- 
Jakub Bogusz    http://qboosh.pl/


Więcej informacji o liście dyskusyjnej pld-devel-pl