The strangest problem....

M

Mattias Ekholm

Hi

The error is indeed a compiler fault! Don't bother what every one else
says. I encountered the same problem with an Alpha processor.

The problem is that the shift assembler instruction with immediate
oparand are only able to contain left shift values up to 23 (all bit
sets in operand field), try investigate the assebler manual for details.

The compiler failes to identify the need for storing the operand in a
register instead.

kind regards
Mattias Ekholm

CBFalconer wrote:

unsigned int* sram_location = (unsigned int *) 0xFF120011;

Undefined behavior here.


Mmmmm, nope.


[#5] An integer may be converted to any pointer type. |
Except as previously specified, the result is
implementation-defined, might not be properly aligned, and
might not point to an entity of the referenced type.49)


49)The mapping functions for converting a pointer to an
integer or an integer to a pointer are intended to be
consistent with the addressing structure of the execution
environment.


Assignment is ok. Use of it is problematic.



Brian Rodenborn


Sorry to post defective code....I was to quick in cutting the problem out of
entire code... I think it is my compiler tricking me :-(, the "unsigned int*
sram_location = (unsigned int *) 0xFF120011" is okay because the code is
intended for a microcontroller that has a peripheral device memory-mapped at
this location.

I solved the problem though, but do still not understand it...I think the
error lies in the compiler and dont think the error is easily seen. When I
did:

*sram_location = ( ((measuredata.n1.number1)<<24) | (
(measuredata.n1.number2)<<16) | ( (measuredata.n2.number3)>>16) );

I got the 0x1A000000

When I do the:
*sram_location = (
((measuredata.n1.number1<<16)<<8) | ((measuredata.n1.number2)<<16) | (
(measuredata.n2.number3) >>16) );
I get the correct result: 0x34000000

Dont ask me why......

Thank you all for your time, effort and patience.

Best Regards
Jannick
 
D

Dan Pop

In said:
Hi

The error is indeed a compiler fault! Don't bother what every one else
says. I encountered the same problem with an Alpha processor.

The problem is that the shift assembler instruction with immediate
oparand are only able to contain left shift values up to 23 (all bit
sets in operand field), try investigate the assebler manual for details.

Nonsense: 24 is NOT a power of two, therefore all bits set in the operand
field cannot encode a value of 23. With an operand field of 4 bits, the
limit is 15, with an operand field of 5 bits, the limit is 31.

Dan
 
D

Dan Pop

In said:
CBFalconer said:
Undefined behavior here.

Mmmmm, nope.


[#5] An integer may be converted to any pointer type. |
Except as previously specified, the result is
implementation-defined, might not be properly aligned, and
might not point to an entity of the referenced type.49)


49)The mapping functions for converting a pointer to an
integer or an integer to a pointer are intended to be
consistent with the addressing structure of the execution
environment.

Assignment is ok. Use of it is problematic.

Nope. There is more to it. First, the quote from the final standard is:

5 An integer may be converted to any pointer type. Except as
previously specified, the result is implementation-defined,
might not be correctly aligned, might not point to an entity of
the referenced type, and might be a trap representation.
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
Assigning a trap representation *is* undefined behaviour. And two
paragraphs later:

7 A pointer to an object or incomplete type may be converted to
a pointer to a different object or incomplete type. If the
resulting pointer is not correctly aligned 57) for the pointed-to
type, the behavior is undefined.

which says that the mere generation of a misaligned pointer invokes
undefined behaviour (it's true that the generation was via a different
mechanism, however).

Dan
 
D

Default User

Dan said:
Nope. There is more to it. First, the quote from the final standard is:

5 An integer may be converted to any pointer type. Except as
previously specified, the result is implementation-defined,
might not be correctly aligned, might not point to an entity of
the referenced type, and might be a trap representation.

Ah yes, that does make a difference.

which says that the mere generation of a misaligned pointer invokes
undefined behaviour (it's true that the generation was via a different
mechanism, however).


I guess it comes down to "possibly undefined behavior". My reading was
that it was safe to generate the construct, but not to use except in
implementation-specific ways. Looks like that's not correct.

Thanks for the correction.



Brian Rodenborn
 
G

Glen Herrmannsfeldt

(snip)
*sram_location = ( ((measuredata.n1.number1)<<24) | (
(measuredata.n1.number2)<<16) | ( (measuredata.n2.number3)>>16) );

I got the 0x1A000000

When I do the:
*sram_location = (
((measuredata.n1.number1<<16)<<8) | ((measuredata.n1.number2)<<16) | (
(measuredata.n2.number3) >>16) );
I get the correct result: 0x34000000

What type of machine is this? It is much easier to answer if we know.

Note that shifting greater than or equal to the number of bits in an
unsigned int is implementation defined. On a 24 bit machine, this may be
the right answer. Is it a 24 bit machine?

-- glen
 
D

Dan Pop

(snip)


What type of machine is this? It is much easier to answer if we know.

Note that shifting greater than or equal to the number of bits in an
unsigned int is implementation defined. On a 24 bit machine, this may be
the right answer. Is it a 24 bit machine?

If it were, how would you explain an output of 0x1A000000, which *cannot*
be represented in 24 bits? Have you forgotten your brain in neutral? ;-)

Dan
 
G

Glen Herrmannsfeldt

Dan Pop said:

(snip)
If it were, how would you explain an output of 0x1A000000, which *cannot*
be represented in 24 bits? Have you forgotten your brain in neutral? ;-)

That is a good question. It does seem, though, that there are machines that
use different widths for different operations. Some CDC machine will do
addition to full 60 bit register width, but multiplication only to 48, or
so. As far as C, it would have to be considered 48 bits, presumably with
12 padding bits.

It is hard to say that anyone would, or would not, limit the shift amount to
less than the full register width, yet still shift all the bits. Most that
I know, take the shift value modulo the register size, but that isn't
required. Especially not with 24 bit or 60 bit registers.

He seems to be reporting values stored in memory, instead of printing them
using C library functions.

It would be much easier to say knowing what the processor was. I believe
the 56001 is a 24 bit processor, but I don't know at all how it does shifts.

-- glen
 
D

Dan Pop

(snip)


It would be much easier to say knowing what the processor was. I believe
the 56001 is a 24 bit processor, but I don't know at all how it does shifts.

Not relevant, since we have direct proof that he's using a processor with
more than 24 bits, according to the 0x1A000000 result.

A *proper* C program illustrating the problem would probably help in
figuring out what is going on.

Dan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,085
Messages
2,570,597
Members
47,219
Latest member
Geraldine7

Latest Threads

Top