J
Jim Cook
We have a macro which takes various index constants as an argument and
offsets into an array. The macro can be an Lvalue or Rvalue. The index
is not zero based. I would like a compile time error displayed if the
index is out of bounds. Is there a way to do this well?
I read through the FAQ that I could find mentioned, and did not see this
sort of question in the preprocessor section anywhere.
What I came up with is below. It does in fact generate errors using my
16-bit and 32-bit compilers, but it feels like I'm relying a little bit
on the behavior of the MS compiler and would like to know a portable
proper C method.
Thank you for any time spent on this.
The code and run-time clip are below. The valid index range is from 20
to 27 inclusive. Any other value should produce an error. Testing for
non-integer is not required.
// #define argument range testing
#include "limits.h"
volatile unsigned short usArray[8];
volatile unsigned short usI;
volatile unsigned char ucArray[8];
volatile unsigned char ucI;
#define usAccess(r) \
(usArray[r-20 + 2*(20<=r && r<=27 ? 0 : INT_MAX)])
#define ucAccess(r) \
(ucArray[r-20 + 2*(20<=r && r<=27 ? 0 : INT_MAX)])
void main(void)
{
usAccess(19) = 19; /* bad */
usAccess(20) = 20;
usAccess(27) = 27;
usAccess(28) = 28; /* bad */
usI = usAccess(19); /* bad */
usI = usAccess(20);
usI = usAccess(27);
usI = usAccess(28); /* bad */
ucAccess(19) = 19; /* bad */
ucAccess(20) = 20;
ucAccess(27) = 27;
ucAccess(28) = 28; /* bad */
ucI = ucAccess(19); /* bad */
ucI = ucAccess(20);
ucI = ucAccess(27);
ucI = ucAccess(28); /* bad */
}
#if 0
------------------ Output ------------------
C:\TEMP\>cl /c /W3 test.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
test.c
test.c(16) : warning C4307: '*' : integral constant overflow
test.c(19) : warning C4307: '*' : integral constant overflow
test.c(20) : warning C4307: '*' : integral constant overflow
test.c(23) : warning C4307: '*' : integral constant overflow
test.c(24) : warning C4307: '*' : integral constant overflow
test.c(27) : warning C4307: '*' : integral constant overflow
test.c(28) : warning C4307: '*' : integral constant overflow
test.c(31) : warning C4307: '*' : integral constant overflow
#endif
offsets into an array. The macro can be an Lvalue or Rvalue. The index
is not zero based. I would like a compile time error displayed if the
index is out of bounds. Is there a way to do this well?
I read through the FAQ that I could find mentioned, and did not see this
sort of question in the preprocessor section anywhere.
What I came up with is below. It does in fact generate errors using my
16-bit and 32-bit compilers, but it feels like I'm relying a little bit
on the behavior of the MS compiler and would like to know a portable
proper C method.
Thank you for any time spent on this.
The code and run-time clip are below. The valid index range is from 20
to 27 inclusive. Any other value should produce an error. Testing for
non-integer is not required.
// #define argument range testing
#include "limits.h"
volatile unsigned short usArray[8];
volatile unsigned short usI;
volatile unsigned char ucArray[8];
volatile unsigned char ucI;
#define usAccess(r) \
(usArray[r-20 + 2*(20<=r && r<=27 ? 0 : INT_MAX)])
#define ucAccess(r) \
(ucArray[r-20 + 2*(20<=r && r<=27 ? 0 : INT_MAX)])
void main(void)
{
usAccess(19) = 19; /* bad */
usAccess(20) = 20;
usAccess(27) = 27;
usAccess(28) = 28; /* bad */
usI = usAccess(19); /* bad */
usI = usAccess(20);
usI = usAccess(27);
usI = usAccess(28); /* bad */
ucAccess(19) = 19; /* bad */
ucAccess(20) = 20;
ucAccess(27) = 27;
ucAccess(28) = 28; /* bad */
ucI = ucAccess(19); /* bad */
ucI = ucAccess(20);
ucI = ucAccess(27);
ucI = ucAccess(28); /* bad */
}
#if 0
------------------ Output ------------------
C:\TEMP\>cl /c /W3 test.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.
test.c
test.c(16) : warning C4307: '*' : integral constant overflow
test.c(19) : warning C4307: '*' : integral constant overflow
test.c(20) : warning C4307: '*' : integral constant overflow
test.c(23) : warning C4307: '*' : integral constant overflow
test.c(24) : warning C4307: '*' : integral constant overflow
test.c(27) : warning C4307: '*' : integral constant overflow
test.c(28) : warning C4307: '*' : integral constant overflow
test.c(31) : warning C4307: '*' : integral constant overflow
#endif