Consider the followig test program:
program TestCast; type BytePtr = ^Byte; IntPtr = ^Integer; var theBytePtr : BytePtr; theIntPtr: IntPtr; begin theBytePtr := nil; theIntPtr:= nil; theIntPtr:= IntPtr( theBytePtr); {testcast.pas:11: warning: cast increases required alignment of target type} BytePtr( theIntPtr) := theBytePtr; theBytePtr:= BytePtr( theIntPtr); IntPtr( theBytePtr):= theIntPtr; {testcast.pas:14: warning: cast increases required alignment of target type} end.
1. Compiling with gpc produces two warnings as indicated in the comment. The compiler warns if the "casting" pointer type (outside the parenthesis) points to a larger type than the "casted" pointer type (inside the parenthesis). Gale Paper brought to my attention that the same holds on the left side of an assignment and I am inclined to regard this as a bug - the compiler should check here for a smaller type, rather than a larger type.
2. the -Wcast-align and -Wno-cast-align command-line switches don't seem to work with gpc.
Regards,
Adriaan van Os
Adriaan van Os wrote:
Consider the followig test program:
program TestCast; type BytePtr = ^Byte; IntPtr = ^Integer; var theBytePtr : BytePtr; theIntPtr: IntPtr; begin theBytePtr := nil; theIntPtr:= nil; theIntPtr:= IntPtr( theBytePtr); {testcast.pas:11: warning: cast increases required alignment of target type} BytePtr( theIntPtr) := theBytePtr; theBytePtr:= BytePtr( theIntPtr); IntPtr( theBytePtr):= theIntPtr; {testcast.pas:14: warning: cast increases required alignment of target type} end.
- Compiling with gpc produces two warnings as indicated in the
comment. The compiler warns if the "casting" pointer type (outside the parenthesis) points to a larger type than the "casted" pointer type (inside the parenthesis).
Not really. As the message says, it warns that the alignment, not size, of the target type is larger.
Gale Paper brought to my attention that the same holds on the left side of an assignment and I am inclined to regard this as a bug - the compiler should check here for a smaller type, rather than a larger type.
While casting to a smaller type can be dangerous in some cases, so can any pointer conversion, so I'm not convinced that this case deserves particular attention.
OTOH, the alignment problem can be unnoticed if during tests the alignment happens to be big enough or the testing platform doesn't require strict alignment (such as IA32), so here a warning seems justified.
- the -Wcast-align and -Wno-cast-align command-line switches don't
seem to work with gpc.
The attached patch should fix that. But be aware that such code may fail (i.e. segfault or bus error), even after extensive testing, unless you verify and prove that the pointer is in fact properly aligned (in which case it might be preferable to keep it in a variable with proper alignment the whole time and leave the warning on, so the compiler will verify this for you).
Frank
Frank Heckenbach wrote:
- Compiling with gpc produces two warnings as indicated in the
comment. The compiler warns if the "casting" pointer type (outside the parenthesis) points to a larger type than the "casted" pointer type (inside the parenthesis).
Not really. As the message says, it warns that the alignment, not size, of the target type is larger.
Gale Paper brought to my attention that the same holds on the left side of an assignment and I am inclined to regard this as a bug - the compiler should check here for a smaller type, rather than a larger type.
While casting to a smaller type can be dangerous in some cases, so can any pointer conversion, so I'm not convinced that this case deserves particular attention.
Well, OK, the warning is about alignments not about sizes. Thanks for pointing that out.
Still I am not convinced that
theIntPtr:= IntPtr( theBytePtr); {testcast.pas:11: warning: cast increases required alignment of target type}
should produce a warning and left-side equivalent shouldn't
BytePtr( theIntPtr) := theBytePtr;
Both statements have the same effect. Actually, the target is in both cases a variable of type Integer. So, at the left side of an assignment, the target is the innermost type of the cast, not the outermost.
The same remarks apply for
theBytePtr:= BytePtr( theIntPtr); IntPtr( theBytePtr):= theIntPtr; {testcast.pas:14: warning: cast increases required alignment of target type}
but then the other way round.
Regards,
Adriaan van Os
Adriaan van Os wrote:
Still I am not convinced that
theIntPtr:= IntPtr( theBytePtr); {testcast.pas:11: warning: cast increases required alignment of target type}
should produce a warning and left-side equivalent shouldn't
BytePtr( theIntPtr) := theBytePtr;
Both statements have the same effect. Actually, the target is in both cases a variable of type Integer. So, at the left side of an assignment, the target is the innermost type of the cast, not the outermost.
I see. I'm adding a warning here (avo9.pas).
The same remarks apply for
theBytePtr:= BytePtr( theIntPtr); IntPtr( theBytePtr):= theIntPtr; {testcast.pas:14: warning: cast increases required alignment of target type}
but then the other way round.
It's more tricky to suppress the warning here since at the time the cast is built, the compiler doesn't know whether it will be used on the LHS or RHS. And since there's an easy alternative (RHS cast) available which is even preferable (LHS casts generally are a strange beast) and a compiler directive to turn of the alignment warnings, I don't think we need to bother.
Frank
Frank Heckenbach wrote:
Adriaan van Os wrote:
Still I am not convinced that
theIntPtr:= IntPtr( theBytePtr); {testcast.pas:11: warning: cast increases required alignment of target type}
should produce a warning and left-side equivalent shouldn't
BytePtr( theIntPtr) := theBytePtr;
Both statements have the same effect. Actually, the target is in both cases a variable of type Integer. So, at the left side of an assignment, the target is the innermost type of the cast, not the outermost.
I see. I'm adding a warning here (avo9.pas).
OK.
The same remarks apply for
theBytePtr:= BytePtr( theIntPtr); IntPtr( theBytePtr):= theIntPtr; {testcast.pas:14: warning: cast increases required alignment of target type}
but then the other way round.
It's more tricky to suppress the warning here since at the time the cast is built, the compiler doesn't know whether it will be used on the LHS or RHS. And since there's an easy alternative (RHS cast) available which is even preferable (LHS casts generally are a strange beast) and a compiler directive to turn of the alignment warnings, I don't think we need to bother.
OK, but I suggest to change the wording to "cast may increase required alignment of target type".
Regards,
Adriaan van Os
Adriaan van Os wrote:
The same remarks apply for
theBytePtr:= BytePtr( theIntPtr); IntPtr( theBytePtr):= theIntPtr; {testcast.pas:14: warning: cast increases required alignment of target type}
but then the other way round.
It's more tricky to suppress the warning here since at the time the cast is built, the compiler doesn't know whether it will be used on the LHS or RHS. And since there's an easy alternative (RHS cast) available which is even preferable (LHS casts generally are a strange beast) and a compiler directive to turn of the alignment warnings, I don't think we need to bother.
OK, but I suggest to change the wording to "cast may increase required alignment of target type".
I understand what you aim at, but the suggested wording may not be quite accurate -- the alignment is increased in any case, but whether that's bad or not depends on the situation, hmm ...
Frank