Can an Objective-C program be compiled so that int is 64 bit? - objective-c

If I remember correctly, on some machine, int was 16 bit, and when we move onto the 32 bit platform, then int was 32 bit.
Now that Snow Leopard and Lion are 64 bit, can a C or Objective-C program be compiled on Xcode so that int is 64 bit? (and "%d" or "%i" will take a 64 bit integer as well). Or is int kept as 32-bit for compatibility reason?
(and if using 64 bit int, will it be faster than 32 bit because 64 bit is native?)
Update: I just found out sizeof(NSInteger) if printed in a console app by Xcode on Lion is 8 (it is typedef as long), and if it is on iOS 5.1.1, then it is 4 (typedef as int). sizeof(int) is 4 on both platforms. So it looks like in a way, int moved from 16 bit to 32 bit before, but now we do want to stop it at 32 bit.

Under the LP64 data model, as adopted by Apple, an int will always be 32-bits. Some compilers might allow you to use the ILP64 data model instead, as explained in the comments here. However, you will likely break compatibility with precompiled libraries.

can a C or Objective-C program be compiled on Xcode so that int is 64 bit?
I have been unable to find a clang option that will make int 64 bits wide. In fact, the platform headers seem to assume that it can't be. Also, you would be unable to use any platform library functions / methods that take an int as a parameter (that includes things like printf() that specify int types in the format string).
and if using 64 bit int, will it be faster than 32 bit because 64 bit is native?
I see no reason why using 32 bit ints would be slower than using 64 bit ints. In fact, possibly, they might be faster since you can fit twice as many of them in the cache.

To get a compiler where int = 64 bit, you'd have to download the Clang source code and modify it by hand. So with existing gcc or Clang compilers, there's no way.
But there is a good reason for int being 32 bits: Lots of code needs for compatibility reasons the ability to have 8 bit, 16 bit, 32 bit, and 64 bit items. The types available in C are char, short, int, long, and long long. You wouldn't want long or long long being smaller than int. If int = 64 bit, you'd only have two types (char and short) for three sizes (8, 16 and 32 bit), so you'd have to give up one of them.

Related

How to demonstrate a memory misalignment error in C on a macbook pro (Intel 64 bit processor)

In an attempt to understand C memory alignment or whatever the term is (data structure alignment?), i'm trying to write code that results in a alignment error. The original reason that brought me to learning about this is that i'm writing data parsing code that reads binary data received over the network. The data contains some uint32s, uint64s, floats, and doubles, and i'd like to make sure they are never corrupted due to errors in my parsing code.
An unsuccessful attempt at causing some problem due to misalignment:
uint32_t integer = 1027;
uint8_t * pointer = (uint8_t *)&integer;
uint8_t * bytes = malloc(5);
bytes[0] = 23; // extra byte to misalign uint32_t data
bytes[1] = pointer[0];
bytes[2] = pointer[1];
bytes[3] = pointer[2];
bytes[4] = pointer[3];
uint32_t integer2 = *(uint32_t *)(bytes + 1);
printf("integer: %u\ninteger2: %u\n", integer, integer2);
On my machine both integers print out the same. (macbook pro with Intel 64 bit processor, not sure what exactly determines alignment behaviour, is it the architecture? or exact CPU model? or compiler maybe? i use Xcode so clang)
I guess my processor/machine/setup supports unaligned reads so it takes the above code without any problems.
What would a case where parsing of say an uint32_t would fail because of code not taking alignment in account? Is there a way to make it fail on a modern Intel 64 bit system? Or am i safe from alignment errors when using simple datatypes like integers and floats (no structs)?
Edit: If anyone's reading this later, i found a similar question with interesting info: Mis-aligned pointers on x86
Normally, the x86 architecture doesn't have alignment requirements [except for some SIMD instructions like movdqa).
However, since you're trying to write code to cause such an exception ...
There is an alignment check exception bit that can be set into the x86 flags register. If you turn in on, an unaligned access will generate an exception which will show up [under linux at least] as a bus error (i.e. SIGBUS)
See my answer here: any way to stop unaligned access from c++ standard library on x86_64? for details and some sample programs to generate an exception.

How 16 bit array needs 5 bit address (Xilinx Vivado HLS)?

I am novice in Xilinx HLS. I am following tutorial ug871-vivado-high-level-synthesis-tutorial.pdf(page 77).
The code is
#define N 32
void array_io (dout_t d_o[N], din_t d_i[N])
{
//..do something
}
After synthesis, I got report like
I am confused that how the width of the address port has been automatically sized match to the number of addresses that must be accessed (5-bit for 32 addresses)?
Please help.
From the UG871, it seems that the size of the array is from 0 to 16 samples, hence you need 32 addresses to access all values (see Figure 69). I guess that the number N is somewhere limited to be less than 32 (or be exactly 16). This means that Vivado knows this limitation, and generates only as many address bits as are needed. Most synthesis tools check the constraints on size and optimize unnecessary code away.
When you synthetise a function you create, also, some registers to store the variables. It means that the address that you put as input is the one of the data that you are concurrently writing in d_o or d_in.
In your case, where N=32, you have 32 different variables (in both input and output). To adress 32 different variables you need 32 different combination of bit (to point to a specific one, without ambiguity). With 5 bit you have 2^5=32 different combination of addresses: the minimum number of bit to address all your data.
For instance if you have 32
The address number of bit is INDIPENDENT from the size of data (i.e. they can be int, float, char, short, double, arbitrary precision and so on)

Why does the C standard provide unsized types (int, long long, char vs. int32_t, int64_t, uint8_t etc.)?

Why weren't the contents of stdint.h the standard when it was included in the standard (no int no short no float, but int32_t, int16_t, float32_t etc.)? What advantage did/does ambiguous type sizes provide?
In objective-C, why was it decided that CGFloat, NSInteger, NSUInteger have different sizes on different platforms?
When C was designed, there were computers with different word sizes. Not just multiples of 8, but other sizes like the 18-bit word size on the PDP-7. So sometimes an int was 16 bits, but maybe it was 18 bits, or 32 bits, or some other size entirely. On a Cray-1 an int was 64 bits. As a result, int meant "whatever is convenient for this computer, but at least 16 bits".
That was about forty years ago. Computers have changed, so it certainly looks odd now.
NSInteger is used to denote the computer's word size, since it makes no sense to ask for the 5 billionth element of an array on a 32-bit system, but it makes perfect sense on a 64-bit system.
I can't speak for why CGFloat is a double on 64-bit system. That baffles me.
C is meant to be portable from enbedded devices, over your phone, to descktops, mainfraimes and beyond. These don't have the same base types, e.g the later may have uint128_t where others don't. Writing code with fixed width types would severely restrict portability in some cases.
This is why with preference you should neither use uintX_t nor int, long etc but the semantic typedefs such as size_t and ptrdiff_t. These are really the ones that make your code portable.

What is meant by "natural unsigned int"

In the documentation for ldlen and localloc the size type is described as "natural unsigned int". Although I have an idea what is meant (on x64: 64 bit unsigned on x86: 32 bit unsigned) I haven't found any documentation for it.
So is there an "official" documentation about the "natural unsigned int"?
The term natural refers, as you thought, to what is native on the hardware. Although it's not specified explicitly in a glossary, you can make it out from other uses of the word natural in the spec:
The native size types (native int,
native unsigned int, and &) are always naturally aligned (4 bytes or 8 bytes, depending on the
architecture).
or
autochar indicates a
platform-specific representation that is “natural” for the underlying platform

Using data type like uint64_t in cgal's exact kernel

I am beginning with CGAL. What I would like to do is to create point that coordinates are number ~ 2^51.
typedef CGAL::Exact_predicates_exact_constructions_kernel K;
typedef K::Point_2 P;
uint_64 x,y;
//init them somehow
P sp0(x,y);
Then I got a long template error. Someone could help?
I guess you realize that changing the kernel may have other effects on your program.
Concerning your original question, if your integer values are smaller than 2^51, then they fit exactly in doubles (with 53 bit mantissa), so one simple option is to cast them to double, as in :
P sp0((double)x,(double)y);
Otherwise, the Exact_predicates_exact_construction_kernel should have its main number type be able to read your uint64 values (maybe cast them to unsigned long long if it's OK on your platform) :
typedef K::FT FT;
P sp0((FT)x,(FT)y);
CGAL Number types are only documented to interoperate with int and double. I recently added some code so we can construct more numbers from long (required for Eigen), and your code will work in the next version of CGAL (except that you typo-ed uint64_t) on platforms where uint64_t is unsigned int or unsigned long (not windows). For long long support, since many of our number types are based on other libraries (GMP) that do not support long long themselves yet, it may have to wait a bit.
Ok. I think that I found solution. The problem was that I used exact Kernel that supports only double, switching to inexact kernel solved the problem. It was also possible to use just double. (one of the requirements was to use data type that supports intergers up to 2^48).