This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Casting Char Pointers to Other Data Types

I just found an insidious and disconcerting characteristic of the uVision3 ARM compiler V3.12a. I have inherited C code to migrate to the ARM processor. This C code uses unsigned char pointers quite liberally to pass the address of data back and forth. The code, of course, casts these generic unsigned char pointers to various data types to access the underlying data.

I have found that if the unsigned char point happens to be pointing at a odd address and it is cast to a short type pointer (e.g., "*(SHORT*)p"), the compiler will resolve the address the previous even address. For a simplistic example, if the address of unsigned char *p happens to be 0x5 and the following code is executed:

	unsigned char	*p;
	...
	*(unsigned short*)p = 0;

rather than address 0x5 and 0x6 being set to zero as one would have expected, address 0x04 and 0x05 are set to zero and address 0x06 is left unchanged.

The same affect is demonstrated if, in the above example, the unsigned char pointer "p" is cast to an unsigned int, except is this case the compiler removes bits 0 and 1 from the address so that it is looking at divisible-by-four address. You could end up unintentionally nailing more nearby data this way.

If you are lucky and the pointer "p" lies on an even address boundary for short type casts of char pointers, the code works just fine, but odd address boundaries definitely are going to cause problems. Similar logic applies to larger standard data types. (Fortunately the code base does no casting to structure pointers, so that is not a problem for me now, but it may be a problem, too).

As I stated, this is inherited code and a major re-write to change the way pointers are deployed is simply not an option. Are there any other ideas out there? I know I can replace every pointer cast to other than an unsigned char with a function call to read or write the data, but frankly unless there is an intuitively obvious solution I'm not seeing, this looks like a huge hole in the compiler logic. Is there any hope for my faith in the Keil folks?

Thanks for any encouragement,
Doug

Parents
  • As I stated, this is inherited code

    Then let me be the one to state it's not worth the electrons it's stored in, as far as porting it to other platforms is concerned. Odds are that porting this stuff will not be noticeably easier or cheaper than rewriting it from scratch.

    and a major re-write to change the way pointers are deployed is simply not an option

    Then I'm afried you've got yourself solidly stuck up that suspiciously brown creek without a canoo. That code you inherited was begging for trouble since its inception, and by porting it to another platform, its prayers have finally been heard. That code will not run on ARM without a major rewrite. So either you re-write, or you forget about using ARM as the platform.

Reply
  • As I stated, this is inherited code

    Then let me be the one to state it's not worth the electrons it's stored in, as far as porting it to other platforms is concerned. Odds are that porting this stuff will not be noticeably easier or cheaper than rewriting it from scratch.

    and a major re-write to change the way pointers are deployed is simply not an option

    Then I'm afried you've got yourself solidly stuck up that suspiciously brown creek without a canoo. That code you inherited was begging for trouble since its inception, and by porting it to another platform, its prayers have finally been heard. That code will not run on ARM without a major rewrite. So either you re-write, or you forget about using ARM as the platform.

Children
  • and a major re-write to change the way pointers are deployed is simply not an option

    Then I'm afried you've got yourself solidly stuck up that suspiciously brown creek without a canoe


    Absolutely.

    I can not count the times I have heard or seen "is simply not an option" and "make it work" about the same issue.

    I recall once in my younger days before I dared to say NO to the brass, I told management that some hardware had to be redone to make the software work. I spent 2 months telling management daily "I need new hardware" before they agreed. When, as a result of this, the project was delayed, it was, of course, my fault.

    The most often occuring issue in this respect is that someone will tell management "this will take 6 months" and management say "we need it in 3". The young engineer afraid of losing his job will say "OK" and finish the project in 9 months.

    Erik

  • and a major re-write to change the way pointers are deployed is simply not an option

    Well, if you are willing to risk losing a lot of time trying this because I neither can nor will guarantee that this will work: Do a global search on "long" and all derivatives thereof and insert an align statement before each and every one. Then do the same for short and int and whatever else you can find more than 8 bits long (such as float). Then, of course you will have to do the same before all arrays and structures and then finally use the debugger to find what you missed and fix that.

    Erik

  • "Odds are that porting this stuff will not be noticeably easier or cheaper than rewriting it from scratch."

    At least it won't be a complete re-write from scratch - you have the old stuff as a reference for what to write, if not how to write it!

    "That code you inherited was begging for trouble since its inception, and by porting it to another platform, its prayers have finally been heard."

    And who knows what other nasties might be lurking?
    Once you've sorted out the pointers, you might start to see byte-ordering problems, packing problems, or who knows what other non-portabilities...

    "a major re-write to change the way pointers are deployed is simply not an option"

    Not an option - a necessity?!

    As you re-write this, be sure to do it in such a way that it still works on the original platform(s)!

  • "And who knows what other nasties might be lurking? Once you've sorted out the pointers, you might start to see byte-ordering problems, packing problems, or who knows what other non-portabilities..."

    I've heard tell that at Sun they had "lint parties".

  • Running lint on the project code would provide some measure of just how bad the code is and could be used as the basis for choosing between fix and rewrite.

  • From http://www.gimpel.com/html/reviews.htm ...

    "ALOA (short for A Lint Output Analyzer) is a tool that processes output generated by PC-lint and computes various useful metrics that give a quick overview of the internal quality of any C/C++ project. Furthermore, it shows which kind of Lint issues are most frequently encountered and highlights issue-laden modules. The metrics produced by ALOA are useful for tracking a project's lint compliance and for fine-tuning Lint policies."