On Tue, Jan 20, 2004 at 02:51:17PM +0100, Marc A. Lehmann wrote: > On Tue, Jan 20, 2004 at 01:24:15AM -0800, Manish Singh <yosh@xxxxxxxx> wrote: > > Well, the bulk of the code in gimp that causes warnings is stuff like: > > > void foo (void **p); > > > > void bar (void) > > { > > int *i; > > foo ((void **) &i); > > } > > > > While it does break the letter of the law wrt aliasing rules, are there any > > assumptions that the compiler can legally make that would cause problems? > > Well, troubling to me would be the fact that a int is not the same as > a void *, so this very example is a bit strange and could likely cause > problems on 64-bit (or else) architectures, but that is, of course, not > the main point. You misread. To explain further: void set_null (void **p) { *p = NULL; } void foo (void) { int *i; set_null ((void **) &i); } Which basically sets i = NULL. I don't see how this can be a problem on a 64-bit architectures, since pointers to all types are the same size. gimp actually only does this with external functions, like: void g_object_add_weak_pointer (GObject *object, gpointer *weak_pointer_location); or gboolean g_module_symbol (GModule *module, const gchar *symbol_name, gpointer *symbol); Perhaps the API should be fixed, I dunno. > I don't know the real case this is based on, but I'd wonder what this code > is supposed to do then. Please note that the warning will not happen when > you cast to a void *, since the pointers might alias then. Sure, I know ways of working it around it. My preferred fix is not to cast to a void *, but use a temporary void * and assign back, since that adds some type safety instead of casting. > Legally, the compiler could cache the contents of i in a register before > and after the call, because foo is not allowed to change it's value. (And > I might guess that foo will not do that, but it's equally hard to see this > as a compiler as it is for a human, so the warning is IMnsO justified). Ah, that answers my question, thanks. > It's unlikely that this will happen with gcc <= 3.5, which is, IMHO, > a viable platform to tie oneself to, but there are no guarentees that > this won't happen in more complicated cases, with other (less or more > intelligent) compilers or with future gcc versions. > > It's hard to judge from his example, but right now it's difficult for > me to imagine a valid use for the above that couldn't easily be written > correctly. > > To repeat it: I am quite certain that the above example will simply work > for quite some time in the future, because of some gcc assumptions about > pointers that are difficult to change but make no good otimized code. > > Perl does similar pointer castings and has opted the safe way by simply > using -fno-strict-aliasing to compile itself at all times, after being > bitten once. > > That might be easier then going through all the code and fixing it, and > will of course silence the warning. Right now, it doesn't make much of a > difference in generated code with gcc, as it is not very good at taking > advantage of (no-) aliasing yet, but this is a hot area in gcc, since > exploiting aliasing rules allow a great deal of optimizations in typical > numerical code. Well, one problem is that flagging every violation like this makes people tend to ignore the warning, which means real problems which affect gcc's alias analysis *now* are likely to be overlooked, or heavy handed solutions like -fno-strict-aliasing put in. It'd be much nicer if this warning didn't trigger for function parameters (except with -pedantic) until gcc was closer to doing the alias analysis that would manifest a problem. As it stands, right now the warning mainly confuses people. It doesn't help that the aliasing rules aren't spelled out anywhere in the gcc docs. I was actually skeptical that gcc might be buggy in this regard, until I dug up the appropriate bits of the standard that say what's going on. -Yosh