# Troubling Alignment (I think) issue.

Discussion in 'C Programming' started by Kevin, Nov 6, 2007.

1. ### KevinGuest

Hey, I was hoping someone out here might be able to clue me in on some
alignment issues I'm having. Hopefully I can explain this best
through code below. ACSign and MyACSign functions below get compiled
(gcc) into one library, where as the code that executes these
functions gets compiled into a seperate library. Calls to MyACSign
work fine, calls to the straight ACSign do not and I believe it is due
to alignment issues, but I can't pinpoint how. This <i>should</i> have
been very elementary. Any help is of course greatly appreciated,

- Kevin

Function Code:
********************************************************************
double ACSign ( double a) {
if (a > 0.0)
return(1.0);
else if (a < 0.0)
return(-1.0);
}

double * MyACSign (double * a) {
if (*a > 0.0)
*a = 1.0;
else if (*a < 0.0)
*a = -1.0;
return a;
}

Execution Code:
********************************************************************
double test = 0 ;
double test1 = 0;
test = 0.707107;
test1 = test * -1;

printf("Locations: %u, %u\r\n", &test, &test1);

printf("0Double: %f, %f", test, test1);
printf("1Double: %f, %f", ACSign(test), ACSign(test1));
printf("2Double: %i, %i", (char)ACSign(test), (char)ACSign(test1));

printf("3Double: %f, %f", 0.707107, -0.707107);
printf("4Double: %f, %f", ACSign(0.707107), ACSign(-0.707107));
printf("5Double: %i, %i", (char)ACSign(0.707107),
(char)ACSign(-0.707107));

printf("6Double: %f, %f", test, test1);
printf("7Double: %f, %f", *(double*)MyACSign(&test),
*(double*)MyACSign(&test1));
printf("8Double: %i, %i", (char)*(double*)MyACSign(&test),
(char)*(double*)MyACSign(&test1));
********************************************************************
The output I get is:
Locations: 4263558272, 4263558264
0Double: 0.707107, -0.707107
1Double: 0.707107, -0.707107
2Double: -98, -98
3Double: 0.707107, -0.707107
4Double: 0.707107, 0.000000
5Double: -98, -98
6Double: 0.707107, -0.707107
7Double: 1.000000, -1.000000
8Double: 1, -1

Kevin, Nov 6, 2007

2. ### Ben PfaffGuest

Kevin <> writes:

> Hey, I was hoping someone out here might be able to clue me in on some
> alignment issues I'm having.

I doubt your problems have anything to do with alignment.
Rather, I suspect that you are not properly declaring the
functions in a header file, e.g.
double ACSign(double);
double *MyACSign(double *);
The prototypes (the bits in parentheses) are optional but they
help the compiler to check the calls.
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1utchar(a[i&15]);break;}}}

Ben Pfaff, Nov 6, 2007

3. ### santoshGuest

On Wednesday 07 Nov 2007 1:57 am Kevin <> wrote in
article <>:

> Hey, I was hoping someone out here might be able to clue me in on some
> alignment issues I'm having. Hopefully I can explain this best
> through code below. ACSign and MyACSign functions below get compiled
> (gcc) into one library, where as the code that executes these
> functions gets compiled into a seperate library. Calls to MyACSign
> work fine, calls to the straight ACSign do not and I believe it is due
> to alignment issues, but I can't pinpoint how. This <i>should</i> have
> been very elementary. Any help is of course greatly appreciated,
>
> - Kevin
>
>
> Function Code:
> ********************************************************************
> double ACSign ( double a) {
> if (a > 0.0)
> return(1.0);

Both the parenthesis and the decimal point are unnecessary.

> else if (a < 0.0)
> return(-1.0);

Similarly here.

> }
>
> double * MyACSign (double * a) {
> if (*a > 0.0)
> *a = 1.0;
> else if (*a < 0.0)
> *a = -1.0;
> return a;
> }
>
> Execution Code:
> ********************************************************************
> double test = 0 ;
> double test1 = 0;
> test = 0.707107;
> test1 = test * -1;
>
> printf("Locations: %u, %u\r\n", &test, &test1);

No. To print pointers use the '%p' specifier and cast the corresponding
argument to void *. Also the '\r' is not only not necessary but may
cause problems. The C Standard library translates a '\n' to whatever
the system uses as end-of-line.

> printf("0Double: %f, %f", test, test1);
> printf("1Double: %f, %f", ACSign(test), ACSign(test1));
> printf("2Double: %i, %i", (char)ACSign(test), (char)ACSign(test1));

What's the point in casting a double value to a char and then passing
them inccorrectly to printf after telling it to look for an int? Use
the '%c' format to print a char.

> printf("3Double: %f, %f", 0.707107, -0.707107);
> printf("4Double: %f, %f", ACSign(0.707107), ACSign(-0.707107));
> printf("5Double: %i, %i", (char)ACSign(0.707107),

Same problems again. Besides what are you expecting to see after a lossy
cast?

> (char)ACSign(-0.707107));
>
> printf("6Double: %f, %f", test, test1);
> printf("7Double: %f, %f", *(double*)MyACSign(&test),

No. Use *(MyACSign(&test)).

> *(double*)MyACSign(&test1));

Similarly.

> printf("8Double: %i, %i", (char)*(double*)MyACSign(&test),
> (char)*(double*)MyACSign(&test1));

Again this mysterious cast to a char value.

> ********************************************************************
> The output I get is:
> Locations: 4263558272, 4263558264
> 0Double: 0.707107, -0.707107
> 1Double: 0.707107, -0.707107
> 2Double: -98, -98
> 3Double: 0.707107, -0.707107
> 4Double: 0.707107, 0.000000
> 5Double: -98, -98
> 6Double: 0.707107, -0.707107
> 7Double: 1.000000, -1.000000
> 8Double: 1, -1

As you have invoked undefined behaviour in several places you could get
any kind of output. I suggest you fix the obvious errors and recompile
and rerun.

santosh, Nov 6, 2007
4. ### KevinGuest

Bingo, I stumbled upon the same answer at the same time - thanks!. I
missed the implied declaration warning in the compiling code and my
partners missed this one function in the header.

Thanks again!

- Kevin

On Nov 6, 3:37 pm, Ben Pfaff <> wrote:
> Kevin <> writes:
> > Hey, I was hoping someone out here might be able to clue me in on some
> > alignment issues I'm having.

>
> I doubt your problems have anything to do with alignment.
> Rather, I suspect that you are not properly declaring the
> functions in a header file, e.g.
> double ACSign(double);
> double *MyACSign(double *);
> The prototypes (the bits in parentheses) are optional but they
> help the compiler to check the calls.
> --
> char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
> ={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa67f6aaa,0xaa9aa9f6,0x11f6}­,*p
> =b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
> 2:{i++;if(i)break;else default:continue;if(0)case 1utchar(a[i&15]);break;}}}

Kevin, Nov 6, 2007
5. ### John GordonGuest

In <> Kevin <> writes:

> Calls to MyACSign work fine, calls to the straight ACSign do not

You're more likely to get useful responses if you describe *exactly* what
is wrong, rather than just saying "it doesn't work".

> The output I get is:
> Locations: 4263558272, 4263558264
> 0Double: 0.707107, -0.707107
> 1Double: 0.707107, -0.707107
> 2Double: -98, -98
> 3Double: 0.707107, -0.707107
> 4Double: 0.707107, 0.000000
> 5Double: -98, -98
> 6Double: 0.707107, -0.707107
> 7Double: 1.000000, -1.000000
> 8Double: 1, -1

Which of these do you think are wrong, and what were you expecting instead?

--
John Gordon A is for Amy, who fell down the stairs
B is for Basil, assaulted by bears
-- Edward Gorey, "The Gashlycrumb Tinies"

John Gordon, Nov 6, 2007
6. ### Eric SosmanGuest

Kevin wrote On 11/06/07 15:27,:
> Hey, I was hoping someone out here might be able to clue me in on some
> alignment issues I'm having. Hopefully I can explain this best
> through code below. ACSign and MyACSign functions below get compiled
> (gcc) into one library, where as the code that executes these
> functions gets compiled into a seperate library. Calls to MyACSign
> work fine, calls to the straight ACSign do not and I believe it is due
> to alignment issues, but I can't pinpoint how. This <i>should</i> have
> been very elementary. Any help is of course greatly appreciated,

My bet is that the calling code has no declarations
for the called functions. This will cause a C99 compiler
to emit a diagnostic, but causes older compilers to assume
that the undeclared function returns an `int' value. Since
the two functions actually return `double' and `double*',
the behavior is undefined. In one case you get garbage:
the returned `double' is getting treated as an `int', or
the function's value is getting plucked from an integer
register instead of from the floating-point register where
the function put it, or something of that sort. In the
other case, it looks like you're lucking out: the `double*'
value seems to be returned in the same way an `int' would
have been, and the conversion from `int' to `double*' is
apparently not damaging it -- but that's not something you
can count on.

> double ACSign ( double a) {
> if (a > 0.0)
> return(1.0);
> else if (a < 0.0)
> return(-1.0);

... and if a == 0.0 exactly ...?

> }

--

Eric Sosman, Nov 6, 2007
7. ### Keith ThompsonGuest

santosh <> writes:
> On Wednesday 07 Nov 2007 1:57 am Kevin <> wrote in
> article <>:

[...]
>> double ACSign ( double a) {
>> if (a > 0.0)
>> return(1.0);

>
> Both the parenthesis and the decimal point are unnecessary.
>
>> else if (a < 0.0)
>> return(-1.0);

>
> Similarly here.
>
>> }

[...]

Yes, the parentheses are unnecessary, and as a matter of style
I strongly prefer *not* to use extra parentheses. So:
return 1.0;
rather than
return(1.0);
The latter looks too much like a function call, and it isn't one.
(But it's perfectly legal, and K&R1 used that style.)

As for the decimal point, presumably you aren't suggesting
return 10;
rather than
return 1.0;
}

I prefer to use floating-point literals for floating-point numbers.
Yes, you can use
return 1;
but ``1'' is of type int, and is implicitly converted to double. The
compiler will almost certainly generate exactly the same code as for
return 1.0;
but I find the more explicit form clearer.

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Nov 7, 2007
8. ### Richard HeathfieldGuest

Keith Thompson said:

> Keith Thompson (The_Other_Keith) [...]
> <http://www.ghoti.net/~kst>

On that page, you write:

<http://www.users.cts.com/king/k/kst/> and..."

No skin, etc, but I thought you might like to know!

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999

Richard Heathfield, Nov 7, 2007
9. ### Keith ThompsonGuest

Richard Heathfield <> writes:
> Keith Thompson said:
>> Keith Thompson (The_Other_Keith) [...]
>> <http://www.ghoti.net/~kst>

>
> On that page, you write:
>
> <http://www.users.cts.com/king/k/kst/> and..."
>
>
> No skin, etc, but I thought you might like to know!

Yeah, my cts.com account died years ago, and I haven't updated my
ghoti.net home page in even longer. I suppose I should either update
it or drop it from my sig.

--
Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
Looking for software development work in the San Diego area.
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Keith Thompson, Nov 7, 2007
10. ### Richard HeathfieldGuest

Keith Thompson said:

<snip>

> Yeah, my cts.com account died years ago, and I haven't updated my
> ghoti.net home page in even longer. I suppose I should either update
> it or drop it from my sig.

I'd leave it until tomorrow if I were you.

Oh, you did.

--
Richard Heathfield <http://www.cpax.org.uk>
Email: -http://www. +rjh@
"Usenet is a strange place" - dmr 29 July 1999

Richard Heathfield, Nov 7, 2007
11. ### Nick KeighleyGuest

On 6 Nov, 20:46, santosh <> wrote:
> On Wednesday 07 Nov 2007 1:57 am Kevin <> wrote in
> article <>:

<snip>

> > printf("Locations: %u, %u\r\n", &test, &test1);

>
> No. To print pointers use the '%p' specifier and cast the corresponding
> argument to void *. Also the '\r' is not only not necessary but may
> cause problems. The C Standard library translates a '\n' to whatever
> the system uses as end-of-line.

very rarely explicit \r is needed when the system output doesn't
match the required output. I've even had to generate \r\r\n!
I suppose the output should have been binary rather than text.
I can't rememeber if it was.

<snip>

--
Nick Keighley

Nick Keighley, Nov 7, 2007
12. ### santoshGuest

On Wednesday 07 Nov 2007 2:13 pm Nick Keighley
<> wrote in article
<>:

> On 6 Nov, 20:46, santosh <> wrote:
>> On Wednesday 07 Nov 2007 1:57 am Kevin <> wrote
>> in article <>:

>
> <snip>
>
>> > printf("Locations: %u, %u\r\n", &test, &test1);

>>
>> No. To print pointers use the '%p' specifier and cast the
>> corresponding argument to void *. Also the '\r' is not only not
>> necessary but may cause problems. The C Standard library translates a
>> '\n' to whatever the system uses as end-of-line.

>
>
> very rarely explicit \r is needed when the system output doesn't
> match the required output. I've even had to generate \r\r\n!
> I suppose the output should have been binary rather than text.
> I can't rememeber if it was.
>
> <snip>

Is such an implementation non-conforming as per the Standard?

santosh, Nov 7, 2007
13. ### Charlie GordonGuest

"santosh" <> a écrit dans le message de news:
fgqjrb\$a8s\$...
> On Wednesday 07 Nov 2007 1:57 am Kevin <> wrote in
> article <>:
>
>> Hey, I was hoping someone out here might be able to clue me in on some
>> alignment issues I'm having. Hopefully I can explain this best
>> through code below. ACSign and MyACSign functions below get compiled
>> (gcc) into one library, where as the code that executes these
>> functions gets compiled into a seperate library. Calls to MyACSign
>> work fine, calls to the straight ACSign do not and I believe it is due
>> to alignment issues, but I can't pinpoint how. This <i>should</i> have
>> been very elementary. Any help is of course greatly appreciated,
>>
>> - Kevin
>>
>>
>> Function Code:
>> ********************************************************************
>> double ACSign ( double a) {
>> if (a > 0.0)
>> return(1.0);

>
> Both the parenthesis and the decimal point are unnecessary.
>
>> else if (a < 0.0)
>> return(-1.0);

>
> Similarly here.
>
>> }

I'm amazed you noticed the extra parentheses and decimal points, and fail to
point at the much more major problem in ACSign: it does not return anything
if a is 0 ;-)
To properly account for negative zero, it should probably return a.

double ACSign(double a) {
return a < 0 ? -1 : a > 0 ? 1 : a;
}

If we don't care about negative zeroes, ACSign should probably return an int
and can be made even more obscure:

int ACSign(double a) { return (a > 0) - (a < 0); }

Any half decent compiler would have complained about the missing return if
configured properly. Indeed it is a shame that most of them don't complain
for such obvious bugs when invoked without extra flags.

--
Chqrlie.

Charlie Gordon, Nov 8, 2007