unsigned long bei 64-Bit Systemen

Vom einfachen Programm zum fertigen Debian-Paket, Fragen rund um Programmiersprachen, Scripting und Lizenzierung.
Antworten
BeWo
Beiträge: 271
Registriert: 21.10.2006 11:17:35

unsigned long bei 64-Bit Systemen

Beitrag von BeWo » 10.09.2007 17:14:25

Hallo,

Auf meinem 64-Bit System beobachte ich etwas merkwürdiges mit dem Datentyp unsigned long.
Dieser Datentyp ist allgemein bekannt ein 32-Bit Datentyp.

Schaut Euch bitte mal folgendes Miniprogramm an:

Code: Alles auswählen

#include <stdio.h>

int main (void)
{
	unsigned long val;
	unsigned char zaehler;
	
	val = (unsigned long)(1);
	
	/* Schiebe Wert von <val> 32-mal nach links */
	for (zaehler=(unsigned char)(0); zaehler<(unsigned char)(32); zaehler++) val *= (unsigned long)(2);
	
	/* Wird bei einer 32-Bit Variable der Wert 1 32-mal nach links geschoben, muss das Ergebnis 0 sein */
	if (val == (unsigned long)(0))
	{
		printf ("OK\n");
	} else
	{
		printf ("FEHLER\nWert ist %lu\n",val);
	}
	
	return (0);
}
In diesem Miniprogramm wird der Wert 1 32-mal nach links geschoben.
Diese Schiebeoperation findet innerhalb einer 32-Bit Variable statt.
Also ist das erwartete Ergebnis 0.
Bei mir ist aber das Ergebnis 4294967296.
Diesen Wert kann eine 32-Bit Variable nicht annehmen.
Meine Vermutung ist, dass der GCC einen unsigned int anstelle eines unsigned long nimmt.
Kann dies jemand bestätigen?

Gruß
Bernhard

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Re: unsigned long bei 64-Bit Systemen

Beitrag von gms » 10.09.2007 17:27:24

BeWo hat geschrieben: Dieser Datentyp ist allgemein bekannt ein 32-Bit Datentyp.
unter Windows, bzw anderen LLP64 Systemen.
Unter 64 bit Linux, bzw auf allen LP64 System (den meisten, wenn nicht auf allen Unix-Plattformen ) ist es 64 bit

Code: Alles auswählen

csxgen2 ~ # cat x.c
#include <stdio.h>
int main() {
 printf("unsigned long: %d bit\n",(int)sizeof(unsigned long)*8);
}
gms2 ~ # gcc -o x x.c && ./x
unsigned long: 64 bit

Gruß
gms

BeWo
Beiträge: 271
Registriert: 21.10.2006 11:17:35

Beitrag von BeWo » 10.09.2007 18:43:24

Ist es nicht so, dass bei ANSI C der Datentyp unsigned long auf jedem System 32-Bit breit sein müsste?
Falls nicht: Gibt es einen Datentyp, welcher auf jedem System 32-Bit breit ist?
Ich würde gerne einen portablen Code erstellen.
Dieser soll sich auf einem 64-Bit Linux AMD System genauso verhalten wie auf einem 8-Bit Mikrocontroller System.

Spasswolf
Beiträge: 3472
Registriert: 30.11.2005 10:32:22
Lizenz eigener Beiträge: MIT Lizenz
Wohnort: Wald

Beitrag von Spasswolf » 10.09.2007 19:09:40

Wie wäre es mit uint32_t?

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 10.09.2007 19:13:55

BeWo hat geschrieben:Ist es nicht so, dass bei ANSI C der Datentyp unsigned long auf jedem System 32-Bit breit sein müsste?
so ungefähr hatte ich das auch einmal in Erinnerung. Ich glaube auch gelernt zu haben, daß "int" maschinenabhängig ist und "short" und "long" dafür immer 16 bzw 32 bit. Das war allerdings noch in der 16 bit Periode.
BeWo hat geschrieben: Falls nicht: Gibt es einen Datentyp, welcher auf jedem System 32-Bit breit ist?
Ich würde gerne einen portablen Code erstellen.
in den meisten Projekten wird über diverse Macros eine "config.h" generiert, mit deren Hilfe dann auch Datentypen konstanter Länge definiert werden können
Unter Linux/Unix ist Autoconf recht populär, für Projekte die auch auf die Microsoft Plattformen portiert werden, empfehle ich gerne "cmake". Dieses unterstützt auch die Visual Studio Formate ( dsp,dsw,sln)


Gruß
gms

BeWo
Beiträge: 271
Registriert: 21.10.2006 11:17:35

Beitrag von BeWo » 11.09.2007 16:16:08

Also jetzt sind alle Klarheiten beseitigt.
Bei der Nachforschung in der stdint.h ist folgendes definiert:
- uint32_t ist ein unsigned int
- uint64_t ist ein unsigned long int
Ich war bis heute immer der Meinung, der Datentyp int wäre Mashinenabhängig und der Datentyp long maschinenunabhängig immer 32Bit.
Wie ist das denn nun?

cosmac
Beiträge: 4576
Registriert: 28.03.2005 22:24:30

Beitrag von cosmac » 11.09.2007 16:59:54

hi,

Im ISO-Standard ist nichtmal die Anzahl der Bits pro Byte festgelegt
A byte is composed of a contiguous sequence of bits,
the number of which is implementation-defined.
Bei den anderen Datentypen ist jeweils nur die minimale Anzahl
der Bits festgelegt:
- int 16
- long 32
- long long 64

Die tatsächliche Bitanzahl ist nicht nur von der Maschine, sondern
auch vom Compiler abhängig und läßt sich manchmal auch noch
mit einen Compiler-Schalter umschalten (z.B. 16/32-Bit-int beim gcc
für den MC68HC12).

das Ziel des Standards ist nämlich:
This International Standard specifies the form and establishes
the interpretation of programs expressed in the programming
language C. Its purpose is to promote portability, reliability,
maintainability, and efficient execution of C language programs
on a variety of computing systems.
Im gcc-Manual stehen ein paar Bemerkungen zu dem Thema und
den Problemen mit Standards.
Beware of programmers who carry screwdrivers.

gms
Beiträge: 7798
Registriert: 26.11.2004 20:08:38
Lizenz eigener Beiträge: MIT Lizenz

Beitrag von gms » 11.09.2007 17:14:03

BeWo hat geschrieben: Ich war bis heute immer der Meinung, der Datentyp int wäre Mashinenabhängig und der Datentyp long maschinenunabhängig immer 32Bit.
Wie ist das denn nun?
falsch
Spasswolf hat geschrieben:Wie wäre es mit uint32_t?
eine wirklich portable Lösung ist das auch nicht, z.B wird dieser Datentyp von Microsoft VC++ nicht unterstützt.
Das muß allerdings nicht umbedingt relevant sein :roll:

dort könnte man aber z.B. auch folgendes machen:

Code: Alles auswählen

#if defined(_MSC_VER)
typedef unsigned __int32 uint32_t;
#endif
Gruß
gms

Antworten