LinuxQuestions.org
Review your favorite Linux distribution.
Home Forums Tutorials Articles Register
Go Back   LinuxQuestions.org > Forums > Non-*NIX Forums > Programming
User Name
Password
Programming This forum is for all programming questions.
The question does not have to be directly related to Linux and any language is fair game.

Notices


Reply
  Search this Thread
Old 10-16-2012, 07:35 AM   #1
VisionIncision
Member
 
Registered: Dec 2011
Location: Wiltshire, UK
Distribution: Slackware, Gentoo
Posts: 130

Rep: Reputation: 3
Learning 64bit C


Hi all,
I am wanting to learn C, but am thinking that it may be worth learning to write 64bit C from the ground up. However, all of the tutorials that I have come across are aimed at writing 32bit code.

Any materials that are available would be appreciated. Also, any input or pointers on how to do so

Regards,
Jack
 
Old 10-16-2012, 07:39 AM   #2
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,869
Blog Entries: 1

Rep: Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870
There is no such thing as "32-bit C" and "64-bit C".
 
Old 10-16-2012, 07:40 AM   #3
VisionIncision
Member
 
Registered: Dec 2011
Location: Wiltshire, UK
Distribution: Slackware, Gentoo
Posts: 130

Original Poster
Rep: Reputation: 3
Quote:
Originally Posted by NevemTeve View Post
There is no such thing as "32-bit C" and "64-bit C".
Ok, well programs written in C that are targeted towards the 64bit architecture. Sorry, should have been clearer.
 
Old 10-16-2012, 08:19 AM   #4
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,869
Blog Entries: 1

Rep: Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870
There are same common problems that arise when you migrate from 32-bit to 64-bit (like assuming that sizeof(int)=sizeof(pointer), but if you start to learn on a 64-bit platform (or better, if you compile your programs in both modes), you won't have these problems.

example:
Code:
$ cat >siz.c <<DONE
/* siz.c */

#include <stdio.h>

int main (void)
{
    printf ("sizeof (char)=%d\n"
            "sizeof (short)=%d\n"
            "sizeof (int)=%d\n"
            "sizeof (long)=%d\n"
            "sizeof (long long)=%d\n"
            "sizeof (void *)=%d\n"
            , (int)sizeof (char)
            , (int)sizeof (short)
            , (int)sizeof (int)
            , (int)sizeof (long)
            , (int)sizeof (long long)
            , (int)sizeof (void *)
           );

    return 0;
}
DONE

$ gcc -m32 -o siz32 siz.c && ./siz32
sizeof (char)=1
sizeof (short)=2
sizeof (int)=4
sizeof (long)=4
sizeof (long long)=8
sizeof (void *)=4

$ gcc -m64 -o siz64 siz.c && ./siz64
sizeof (char)=1
sizeof (short)=2
sizeof (int)=4
sizeof (long)=8
sizeof (long long)=8
sizeof (void *)=8
 
1 members found this post helpful.
Old 10-16-2012, 08:22 AM   #5
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Programs in C ought to be written portably, so they work despite differences between 32-bit and 64-bit.

For most programs, that isn't even an issue. It tends to take pretty advanced programming to even create a situation in which the natural way to code something is non portable and extra effort is then required to make it portable.

For example, the single most common non portable usage is assuming that an int and a pointer are the same size (which is true in x86 and other typical 32-bit architectures but false in x86_64 and some other 64-bit architectures). A beginner probably never sees a situation in which there would be any reason to make such an assumption, so avoiding such assumptions doesn't take any effort at all.

In more abstract programming, you often have a situation in which a parameter is passed from code that knows its type to ultimately reach other code that knows its type, but in between goes through code that doesn't know the type. You can do that correctly with a union. But it is enough easier via casts that many programmers have accidentally inserted non portable assumptions about size via such casts.
 
3 members found this post helpful.
Old 10-16-2012, 08:49 AM   #6
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
If you expect to care about performance, there is one programming habit I would start early because of its benefits in x86_64 architecture (it does no harm in x86 or other architectures):

Invent an index type and use a typedef to make it the same as unsigned int
Code:
typedef unsigned int index_t;
Then, whenever you have a variable that counts or indexes elements of an array, or a variable that loops through moderate size non negative values, use that type instead of using (what most people use) int.

Code:
for (index_t n= ...)
instead of
Code:
for (int n= ...)
When doing this (using unsigned int instead of size_t) you are limiting your program to 4 billion elements in any one array. But when you think about that, you realize it is not much of a limit. A 64-bit program can use far more than 4GB of memory without approaching 4G elements in one array. It may even have more than 4G Bytes in one array of structs without close to 4G structs in that array.

By using a typedef, you make it easy to change the program later, when problem size has grown so much that 4G elements per array is a real limit.

By using unsigned int now, you get better code now.

In 32-bit, int and unsigned int and size_t all perform exactly the same in the binary code, so in the common case where any one of them is correct, there is no performance difference either.

But in x86_64, in the common loop and index situations where any one of those types would give the right results, unsigned int tends to cause the compiler to generate smaller binary instructions (compared to either int or size_t) creating lots of situations in which the interaction between the L1 cache and the instruction pre fetch runs more smoothly, creating code that runs slightly faster (despite the actual operations of unsigned int being the same nominal speed as those with size_t). (int often needs extra instructions for sign extend where a non asm programmer wouldn't expect such a difference).

I expect most other experts would argue in favor of going directly to size_t, so that you don't need to guess at the time you write the program whether someone will use it later with arrays over 4G elements. Whether you agree with them or with me, part of the suggestion is the same: In 32-bit C programming you see a lot of indexes that are declared as int. In 64-bit C programming, int usually works as an index, but using it is a very bad habit to get into.

Last edited by johnsfine; 10-16-2012 at 08:58 AM.
 
2 members found this post helpful.
Old 10-16-2012, 10:12 AM   #7
sundialsvcs
LQ Guru
 
Registered: Feb 2004
Location: SE Tennessee, USA
Distribution: Gentoo, LFS
Posts: 10,671
Blog Entries: 4

Rep: Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945Reputation: 3945
I would strongly echo JohnsFine's advice here, because when you define the string size_t (or whatever it may be), you are defining ... in one easily-found and easily-changed place ... a word that has meaning. In other words, size_t foo; is saying both to the computer (who really doesn't care) and to the programmer (who does!!) that "foo is a size_t."

It's very important when writing code to make your intentions clear, not just to the computer but also to the person who's picking-up after you following "that very unfortunate incident involving the bread truck." (Your funeral is next Friday...) Simple tricks like the one he suggests not only make the code more portable, but also more meaningful. In some cases and with some (other) languages they can also enable the compiler to detect the kind of "niggling mistakes" that are so often the consequence of an un-noticed tpyo. (The hair-follicles that you save will be your own, and the day will come, at least for all you gentlemen out there, when that is very important.)
 
1 members found this post helpful.
Old 10-16-2012, 11:16 AM   #8
johnsfine
LQ Guru
 
Registered: Dec 2007
Distribution: Centos
Posts: 5,286

Rep: Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197Reputation: 1197
Quote:
Originally Posted by sundialsvcs View Post
when you define the string size_t (or whatever it may be), you are defining ...
Just to be clear, when I mentioned size_t, I meant the standard one described here
http://en.wikipedia.org/wiki/C_data_...fference_types

When I used the example of index_t I was suggesting defining your own type name, for situations where a careless or beginner programmer would use int without thinking and where a careful programmer writing portable code might correctly use (the standard) size_t. In those situations, I prefer defining and using my own type name for the reasons described above.

In x86_64, size_t is a 64 bit unsigned integer, which can make it slower in many situations where a 32 bit unsigned integer is good enough.

Last edited by johnsfine; 10-16-2012 at 11:20 AM.
 
1 members found this post helpful.
Old 10-16-2012, 11:33 AM   #9
VisionIncision
Member
 
Registered: Dec 2011
Location: Wiltshire, UK
Distribution: Slackware, Gentoo
Posts: 130

Original Poster
Rep: Reputation: 3
Thanks for the responses. I think it'll be easier to abide by these pieces of advice if I get in habit of following them right from the beginning.

Thanks again.
 
Old 10-16-2012, 11:37 AM   #10
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,869
Blog Entries: 1

Rep: Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870
If I might risk a guess, in actual programs you cannot win considerable CPU-time via using 32 bit long variables as indices instead of 64 bit longs -- especially when they reside in registers.
 
Old 10-17-2012, 09:48 AM   #11
suttiwit
Member
 
Registered: Aug 2012
Location: Chiang Mai, Thailand
Distribution: Kubuntu 12.10 x86_64
Posts: 192
Blog Entries: 2

Rep: Reputation: 23
Okay, here is a little bit different output when you compile this code on both 32-bit and 64-bit OS:
Code:
/* Successfully compiled with: gcc -std=c99 -Wall test.c */
#include <stdio.h>
#include <time.h>

int main(void)
{
     time_t current_time = time(NULL);
     for (;;)
     {
          printf("Fast time: %s\n", ctime(&current_time));
          current_time += 9999; // 999 or 9999 is up to you.
     }
     return 0;
}
After sometime, you should see the difference that the time on the 32-bit OS has been reset from 2038 to 1901.
While on the 64-bit OS, It keeps on going.
 
1 members found this post helpful.
Old 10-17-2012, 10:11 AM   #12
NevemTeve
Senior Member
 
Registered: Oct 2011
Location: Budapest
Distribution: Debian/GNU/Linux, AIX
Posts: 4,869
Blog Entries: 1

Rep: Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870Reputation: 1870
Good point: never assume that time_t is equal to int. (In Unix, it is equal to long, but that may change without warning.)

Other types, like off_t an ino_t, depend on compiler options:

-m32, without LargeFileSupport: 32 bit
-m32, with LargeFileSupport: 64 bit
-m64: 64 bit
 
Old 10-17-2012, 09:53 PM   #13
suttiwit
Member
 
Registered: Aug 2012
Location: Chiang Mai, Thailand
Distribution: Kubuntu 12.10 x86_64
Posts: 192
Blog Entries: 2

Rep: Reputation: 23
Quote:
Originally Posted by suttiwit View Post
Okay, here is a little bit different output when you compile this code on both 32-bit and 64-bit OS:
Code:
/* Successfully compiled with: gcc -std=c99 -Wall test.c */
#include <stdio.h>
#include <time.h>

int main(void)
{
     time_t current_time = time(NULL);
     for (;;)
     {
          printf("Fast time: %s\n", ctime(&current_time));
          current_time += 9999; // 999 or 9999 is up to you.
     }
     return 0;
}
After sometime, you should see the difference that the time on the 32-bit OS has been reset from 2038 to 1901.
While on the 64-bit OS, It keeps on going.
If forgot to add that:
For 32-bit systems though, there is a little hack on this but it does not work with ctime();
Code:
/* Successfully compiled with: gcc -std=c99 -Wall test.c */
#include <stdio.h>
#include <time.h>

int main(void)
{
     unsigned long long current_time = time(NULL);
     for (;;)
     {
          printf("Fast time: %llu\n", current_time);
          current_time += 9999; // 999 or 9999 is up to you.
     }
     return 0;
}
Time will not reset on 2038. But still: ctime() does not want to convert.
 
  


Reply

Tags
64bit



Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Which 64bit Debian Wheezy Release is wright for my Intel 64bit P8700 CPU PC? esgol Linux - Newbie 15 07-15-2012 03:50 PM
Which 64bit Debian wheezy Release is wright for my Intel 64bit P8700 CPU? esgol Linux - Newbie 1 07-15-2012 03:11 AM
[SOLVED] 64bit Linux versions write they are for amd64. Combatible for Intel 64bit also? esgol Linux - Newbie 2 07-13-2012 02:07 AM
64bit RPM installation is failing on SLES-10/11 but working fine on RHEL4/5 64bit os raghuhb Linux - Software 2 11-06-2009 07:31 AM
Can't install amarok 64bit du eto missing provider of libpq.so.4()(64bit) Ossah Linux - Software 1 04-21-2007 09:23 PM

LinuxQuestions.org > Forums > Non-*NIX Forums > Programming

All times are GMT -5. The time now is 10:55 AM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Open Source Consulting | Domain Registration