[comp.sys.mac.programmer] Huh? What's wrong here...

jpmah@dahlia.uwaterloo.ca (John Mah) (04/14/91)

Ok. Simple it is, but I still can't figure out what's wrong:

I have a function:

long _get_new_hash_val(some parameters) 
etc, etc...
{
	long value;
	...some statements...
	return value;
}

Now, I call it with:

*my_pointer_to_a_long = _get_new_hash_val(some parameters);

Ok, it compiles fine and everything, but (upon examination with the ThinkC 
debugger) that when I hit the return function, value = 0x2CEDE78A. 
Now after I execute the *my_pointer_to_a_long assignment, it has a value of
0xFFFFE78A. What is happening is that the assignment is cutting off the two
high bytes, but keeping the two low bytes.

My question is: "Why does it do that and how can I fix it?". Thanks in advance.
(PS. I'm using Think C 4.0.2 -- great package)

-- John

c90davby@odalix.ida.liu.se (David Byers) (04/14/91)

jpmah@dahlia.uwaterloo.ca (John Mah) writes:

>Ok. Simple it is, but I still can't figure out what's wrong:

>I have a function:

>long _get_new_hash_val(some parameters) 
>etc, etc...
>{
>	long value;
>	...some statements...
>	return value;
>}

>Now, I call it with:

>*my_pointer_to_a_long = _get_new_hash_val(some parameters);

>Ok, it compiles fine and everything, but (upon examination with the ThinkC 
>debugger) that when I hit the return function, value = 0x2CEDE78A. 
>Now after I execute the *my_pointer_to_a_long assignment, it has a value of
>0xFFFFE78A. What is happening is that the assignment is cutting off the two
>high bytes, but keeping the two low bytes.

>My question is: "Why does it do that and how can I fix it?". Thanks in advance.
>(PS. I'm using Think C 4.0.2 -- great package)

My guess, and is is only a guess, since I have not seen all of your
source code, is that when you call _get_new_hash_val() from a file
other than the one it is defined in, the top two bytes are cut off.
That is due to the fact that the ANSI specs say the an undeclared
function is assumed to take any number of parameters, and redurns in
int, and that an int is equivalent of a short int in THINK C, that is
two bytes.

To fix it you need to declare _get_new_hash_val() in the file/function
you are using it. That can either be accomplished by creating a header
file (like hashfuns.h, or whatever you wand), and place the line:

long _get_new_hash_val([Your parameters go here]);

in it. While you are at it, do the same for all other functions in the
file. Then #include the header file in every finle that uses functions
that are declared in the header. If you do not want to create a header
file, you can put the line:

extern long _get_new_hash_val();

in the declaration section of the file/function/block hat uses
_get_new_hash_val().

C compilers (mercifully) does not complain if a function called is not
declared, but the compiler willl make certain assumptions, leaving it
to the linker to find the function. The linker, however, will scream
its head off if a function is not defined.

--
 _____________________________________  ____________________________________
| David Byers                         ||SnailMail:     David Byers          |
| 				      ||               Ryds Alle 9:204      |
| c90davby@odalix.ida.liu.se          ||               S-58251 Linkoping    |
| byers@nanny.lysator.liu.se          ||               SWEDEN               |
`-------------------------------------'`------------------------------------'

rmitchel@bbn.com (Rob Mitchell) (04/27/91)

>jpmah@dahlia.uwaterloo.ca (John Mah) writes:

>long _get_new_hash_val(some parameters) 
>{
>	long value;
>	...some statements...
>	return value;
>}

>*my_pointer_to_a_long = _get_new_hash_val(some parameters);

	Use prototyping and declare the function in the file/module that its
	being called from.  Problem is the 68000 masks off hiword (look at
	some disassembled code) upon return from function calls defaulting
	to "int" (which is only 16-bits on Mac, not 32-bits like many Unix
	machines).

	IMHO, never use "int" when programming Mac.  Use either "short" or
	"long" (or better, declare typedefs for Int8, UInt8, etc.) which
	helps when porting to other computer systems.

	Good luck!!


	
Rob Mitchell                            Advanced Simulation Division
Unix & Macintosh Engineer               BBN Systems & Technologies
Internet: rmitchel@vax.bbn.com          33 Moulton Street   MS: 8/C
Primary Dwelling:   617-873-4041        Cambridge, MA  02138
Secondary Dwelling: 617-873-4071
FAX:                617-873-4315

These opinions are mine and mine only.  They do not represent BBNs' opinions.

guido@cwi.nl (Guido van Rossum) (04/29/91)

rmitchel@bbn.com (Rob Mitchell) writes:

>[correct diagnosis of earlier problem omitted]
>	IMHO, never use "int" when programming Mac.  Use either "short" or
>	"long" (or better, declare typedefs for Int8, UInt8, etc.) which
>	helps when porting to other computer systems.

I take exception with this advice.  Portable programs should use 'int'
for most common cases, especially function parameters, except:

	- always use long if values > 32767 are possible
	- use short for space conservation in structs and arrays,
	  when values are guaranteed to be <= 32767.

The reason is that 'int' is likely to generate the most efficient
code, because it represents the natural word size (register size) for
the architecture.

--Guido van Rossum, CWI, Amsterdam <guido@cwi.nl>

ksand@Apple.COM (Kent Sandvik) (04/29/91)

In article <3417@charon.cwi.nl> guido@cwi.nl (Guido van Rossum) writes:
>rmitchel@bbn.com (Rob Mitchell) writes:
>>[correct diagnosis of earlier problem omitted]

>>	IMHO, never use "int" when programming Mac.  Use either "short" or
>>	"long" (or better, declare typedefs for Int8, UInt8, etc.) which
>>	helps when porting to other computer systems.

>I take exception with this advice.  Portable programs should use 'int'
>for most common cases, especially function parameters, except:

>	- always use long if values > 32767 are possible
>	- use short for space conservation in structs and arrays,
>	  when values are guaranteed to be <= 32767.
>
>The reason is that 'int' is likely to generate the most efficient
>code, because it represents the natural word size (register size) for
>the architecture.

This is true, with the exception of the Macintosh programming world,
where programmers may or may not move source and header files between
MPW and Think environments. Anyway, most of the optimization issues
are really oriented towards 32-bit quantities with the M68k architecture
(passing on the stack, fetching on the databus and so on).

Anyway, I would also recommend to use short and longs in order to 
avoid any problematic portability problems *within the Mac 
development world*.

TN#200 is kind of out-of-date (and we will update the TN soon!), but
one thing that is relevant in this tech note is the issue of widening
and narrowing of basic types with the MPW C compiler. Thus char and
short are widened to int (long) size before being passed as 
function arguments (and narrowed back to char or short in the
function). So any possible optimization by using short is not
present, with the exception of struct handling, and in many cases
the structs are also padded to full 32-bit boundaries.

Speaking about other nasty type problems concerning portability, character
constants are char in C++, and ints in C :-).

Regards,
Kent Sandvik
-- 
Disclaimer: Private and personal activities on USENET, non-company sponsored

rmitchel@bbn.com (Rob Mitchell) (05/01/91)

guido@cwi.nl (Guido van Rossum) writes:

>rmitchel@bbn.com (Rob Mitchell) writes:

>>[correct diagnosis of earlier problem omitted]
>>	IMHO, never use "int" when programming Mac.  Use either "short" or
>>	"long" (or better, declare typedefs for Int8, UInt8, etc.) which
>>	helps when porting to other computer systems.

>I take exception with this advice.  Portable programs should use 'int'
>for most common cases, especially function parameters, except:

>	- always use long if values > 32767 are possible
>	- use short for space conservation in structs and arrays,
>	  when values are guaranteed to be <= 32767.

>The reason is that 'int' is likely to generate the most efficient
>code, because it represents the natural word size (register size) for
>the architecture.

	Then just use "register" wherever possible.  Global variable "ints"
	are, IMHO, next to useless.

	This is not place for further programming-style-bashing.


Rob Mitchell                            Advanced Simulation Division
Unix & Macintosh Engineer               BBN Systems & Technologies
Internet: rmitchel@vax.bbn.com          33 Moulton Street   MS: 8/C
Primary Dwelling:   617-873-4041        Cambridge, MA  02138
Secondary Dwelling: 617-873-4071
FAX:                617-873-4315

These opinions are mine and mine only.  They do not represent BBNs' opinions.