Troubling Alignment (I think) issue.

K

Kevin

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
 
B

Ben Pfaff

Kevin said:
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.
 
S

santosh

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.
 
K

Kevin

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


Kevin said:
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 1:putchar(a[i&15]);break;}}}
 
J

John Gordon

In said:
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?
 
E

Eric Sosman

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 ...?
 
K

Keith Thompson

santosh said:
article <[email protected]>: [...]
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;
:cool:}

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.
 
K

Keith Thompson

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

On that page, you write:

"Versions of this page are available at
<http://www.users.cts.com/king/k/kst/> and..."

but the cts link is dead.

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.
 
R

Richard Heathfield

Keith Thompson said:

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. :)
 
N

Nick Keighley

article <[email protected]>:


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>
 
S

santosh

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?
 
C

Charlie Gordon

santosh said:
Both the parenthesis and the decimal point are unnecessary.


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.
 

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
473,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top