Frage zu Typedef
-
@H-P-Wurst sagte in Frage zu Typedef:
@Wutz Also ich benutze Visual Studio 2020. Wie kann ich denn bei VS einen C-Compiler benutzen?
Indem du die Source-Datei mit der Endung .c abspeicherst oder in den Compiler Optionen das entsprechend einstellst.
-
@Swordfish Das Skript mit dem ich arbeite ist aufgeteilt in einen C- und einen C++ Teil. Momentan bin ich noch im C-Teil
-
Also so funktioniert es jetzt:
#include <stdio.h> typedef struct emp_struct { char name[10]; int employee_no; float salary, tax_to_date; } Employee; typedef Employee Database[10]; void swap(Employee* emp1, Employee* emp2) { Employee temp; temp = *emp1; *emp1 = *emp2; *emp2 = temp; } void sort(Database people, int n, int str_size) { int i, j; for (i = 0; i < n - 1; i++) for (j = i + 1; j > 0; j--) if (strcmp(people[j].name, people[j - 1].name) < 0) swap(&people[j], &people[j - 1]); else if (strcmp(people[j].name, people[j - 1].name) == 0) if (people[j].employee_no < people[j - 1].employee_no) swap(&people[j], &people[j - 1]); } int main() { int i, n, str_size; n = 10; str_size = 10; Database people = /*initializer: real DB would read from disk*/ { {"Fred", 10, 10000, 3000}, {"Jim", 9, 12000, 3100.5}, {"Fred", 13, 1000000, 30}, {"Mary", 11, 170000, 40000}, {"Judith", 45, 130000, 50000}, {"Nigel", 10, 5000, 1200}, {"Trevor", 10, 20000, 6000}, {"Karen", 10, 120000, 34000}, {"Marianne", 10, 50000, 12000}, {"Mildred", 10, 100000, 30000} }; sort(people, n, str_size); for (i = 0; i < n; i++) printf("Name%d: %s, Mitarbeiternummer: %d \n", i, people[i].name, people[i].employee_no); }
-
@H-P-Wurst sagte in Frage zu Typedef:
@Swordfish Das Skript mit dem ich arbeite ist aufgeteilt in einen C- und einen C++ Teil. Momentan bin ich noch im C-Teil
Dein Script ist falsch. Such dir bitte was anderes. Wurde dir schon gesagt, hast du aber nicht ernst genommen. Musst du aber. Falsches Lehrmaterial ist das schlimmst, was du dir antun kannst. Und ganz wichtig: Entscheide dich für eine Sprache. Wenn ein Buch dir C und C++ beibringen möchte, dann bringt es dir keines davon bei.
-
@H-P-Wurst sagte in Frage zu Typedef:
Also so funktioniert es jetzt:
void sort(Database people, int n, int str_size)
Ohje, wieder ein Skript was nicht die korrekten Typen für die Größe von Strings verwendet.
int
ist dafür nicht ausreichend. Früher (in der guten alten Zeit mit 16Bit Computern oder den ersten 32Bit Systemen) mag das noch funktioniert haben. Mittlerweile kann man in Intels bzw. AMD aktuelle Desktop Plattform 128GB RAM verbauen, da ist es sehr einfach mehr als 2GB für einen String zu verwenden. Der korrekte Typ istsize_t
bzw. wenn man es Vorzeichen behaftet haben willssize_t
.
-
@john-0 sagte in Frage zu Typedef:
Ohje, wieder ein Skript was nicht die korrekten Typen für die Größe von Strings verwendet.
Nicht alles, was str im Namen hat, wird für Strings verwendet. Und hier wird die Variable gar nicht benutzt.
-
@manni66 sagte in Frage zu Typedef:
Nicht alles, was str im Namen hat, wird für Strings verwendet. Und hier wird die Variable gar nicht benutzt.
Es ändert nichts daran, dass im gesamten Code Variablen des Typs
int
verwendet werden, um über dynamische allozierte Felder zu iterieren. Das ist ein Programmfehler.
-
@john-0 sagte in Frage zu Typedef:
Der korrekte Typ ist size_t bzw. wenn man es Vorzeichen behaftet haben will ssize_t.
Rede nur von Sachen, von denen du Ahnung hast. ssize_t ist nur POSIX und kein Bestandteil von ISO C.
-
@Wutz sagte in Frage zu Typedef:
Rede nur von Sachen, von denen du Ahnung hast. ssize_t ist nur POSIX und kein Bestandteil von ISO C.
Das von jemanden, der das
int
Problem unkommentiert durchgehen lässt. Das ergibt UB. Ja,ssize_t
ist aus POSIX, aber der Compiler würde das Problem anmerken. Deshalb hatte ich das nicht korrigiert.
-
@john-0 sagte in Frage zu Typedef:
aber der Compiler würde das Problem anmerken
LOL
Leute die nach dem Motto programmieren "der Compiler wirds schon merken" - wann hast du das letzte Mal produktionsrelevanten Code geschrieben, der das mehrstufige Codereview überstanden hat?
Trolle dich.
-
@Wutz sagte in Frage zu Typedef:
Leute die nach dem Motto programmieren "der Compiler wirds schon merken" - wann hast du das letzte Mal produktionsrelevanten Code geschrieben, der das mehrstufige Codereview überstanden hat?
Entweder ist
ssize_t
definiert, oder es ist nicht definiert. Da kann nichts passieren. Aber du reißt hier die Klappe gewaltig auf und lässt UB durchgehen! Wer ist denn hier der Totalversager was produktionsrelevanten Code anbelangt?
-
@john-0
Nonsens.
Depp.
Mit deinen Ansichten wärst du bei mir im Review gleich rausgeflogen und ich hätte dich zum FirstLevel-Support versetzt, da kannst du mit deinem aufgeschnappten Halbwissen nicht soviel Unheil anrichten.
Hier ist bzgl. int nirgendwo UB.
Array-subscript zerfällt in Pointerarithmetik, wobei der eine Operand immer ein Zeiger auf einen (vollständigen) Objekttyp und der andere immer von einem beliebigen Integraltyp (oder enum) ist, nirgends wird hier im Standard size_t gefordert, das hast du irgendwo aufgeschnappt und propagierst es hier als UB. (dass hierbei höchstens noch die arithmetic promotion mal mit reinspielt, ändert nichts am Grundsatz, d.h. wenn überhaupt wird in diesem Zusammenhang (implizit) int genannt aber niemals size_t).
Du hast Pointerarithmetik nicht verstanden und propagierst dein aufgeschnapptes Halbwissen als UB - ein Begriff, den du auch irgendwo aufgeschnappt hast und in deinem beschränkten Horizont einfach nachplapperst.
Ich empfehle dir N1570 und dort die Kapitel 6.*; wenn du das gelesen, verinnerlicht und in 30 Jahren C-Programmierung nachgewiesen hast es verstanden zu haben, kannst du hier mal wieder vorstellig werden.
Du hast keine Ahnung.
Trolle dich.
-
@Wutz sagte in Frage zu Typedef:
@john-0
Nonsens.
Depp.
Ich empfehle dir N1570 (...)
Du hast keine Ahnung.
Trolle dich.Ach. Ad hominem. Toll.
Sagt der, der aus @john-0 s Aussage, dass int nicht ausreichend ist, wenn int 32 bit hat und man mehr als 2GB große Objekte haben möchte, irgendwas über Array-Subscript herleitet?
Ich zitiere mal aus N1570. Kapitel 7.24.1 [String function conventions] - aber eigentlich auch egal, wo:
1 The header <string.h> declares one type and several functions, and defines one
macro useful for manipulating arrays of character type and other objects treated as arrays
of character type.307) The type is size_t and the macro is NULL (both described in
7.19).So, und deiner Meinung nach soll man da lieber int nutzen? Warum wird dann überall in den C-Funktionen wie malloc, memcpy etc. nicht der Parametertyp int gewählt, sondern size_t?
-
@wob Der Programmierer darf ruhig sein Expertenwissen mit ein bringen, ob int reicht oder size_t nötig ist.
-
Kann man das nicht in einen eigenen Thread auslagern?
-
@wob sagte in Frage zu Typedef:
Sagt der, der aus @john-0 s Aussage, dass int nicht ausreichend ist, wenn int 32 bit hat und man mehr als 2GB große Objekte haben möchte, irgendwas über Array-Subscript herleitet?
Noch ein Naivling.
Das was du "irgendwas" nennst ist tiefste Pointerarithmetik, also C Grundlagen. Und der Standard hat den Anspruch, eben unabhängig vom Knowhow gewisser Programmierer immer zu gelten, und beschreibt eben genau keine konkreten Annahmen über Bitbreiten und Gigabytes.
Und deshalb ist der Gebrauch des Standard-Terms "UB" hier sinnfrei und einfach nur falsch, weil der Standard gerade nicht für konkrete Laufzeitbedingungen geschaffen wurde.
Wer nicht begreift, was der Standard eigentlich bedeutet und für welche Kontexte er gilt, trotzdem aber der Meinung ist, sich aus dessen Sprachgebrauch bedienen zu müssen, desavouiert sich als ahnungsloser Depp, der ungefragt aufgeschnapptes Halbwissen daherplappert.
Den einzigen Bezug zum Standard bzgl. des gezeigten Codes habe ich aufgezeigt, und wenn du das nicht verstehst, halte einfach die Klappe.
-
@Wutz sagte in Frage zu Typedef:
Array-subscript zerfällt in Pointerarithmetik, wobei der eine Operand immer ein Zeiger auf einen (vollständigen) Objekttyp und der andere immer von einem beliebigen Integraltyp (oder enum) ist, nirgends wird hier im Standard size_t gefordert, das hast du irgendwo aufgeschnappt und propagierst es hier als UB.
Wie sehr willst du dich noch selbst bloßstellen? Jemand mit Intelligenz hätte die Sache nochmals nachgelesen. Du legst hier wieder einen drauf. Meinst du mit aggressiven Verhalten könntest du deine Inkompetenz überdecken?
int
ist auf modernen Betriebssystemen ein 32Bit Datentyp unabhängig davon, ob man sich im 32Bit oder 64Bit Modus befindet.size_t
expandiert je nach Modus in 32Bit oder 64Bit, passend zur Zeigergröße und den maximalen Feldgrößen. D.h. es garantiert, dass man mit einemsize_t
Indextyp über ein Feld iterieren kann.Du darfst gerne im nachfolgenden Beispiel, die Funktion
wutz_strcpy
durch eine von dir optimierte Version ersetzen. Die Randbedingungen sind, es wird keine direkte Zeigerarithmetik gemacht (also keine üblen Tricks wie Zeiger mitp++
hochzählen) und als Indextyp für den Feldzugriff nimmst du wie du die ganze Zeit behauptest bitte schönint
.Ergänzung: Im 64Bit Modus zu übersetzen.
#include <stdlib.h> #include <stdio.h> #include <string.h> #include <limits.h> #include <stdint.h> char* wutz_strcpy (char* dest, const char* src) { int src_length = strlen (src); printf("wutz length %d\n", src_length); src_length++; // just for copying the nul byte for (int i = 0; i < src_length; ++i) { dest[i] = src[i]; } return dest; } int main () { size_t string_length = 0x00000000FFFFFFFF; string_length += 20; char* short_dest = malloc(32); char short_string[] = "This is a short example string."; printf("Testing the wutz like function with a short example.\n"); wutz_strcpy (short_dest, short_string); printf("Short example string, before copy with wutz like function: %s\n", short_string); printf("Short example string, after copy with wutz like function: %s\n", short_dest); free(short_dest); // no with large strings printf ("\nJust as to remember the sizes of some C data types, and the size of our long example\n"); printf ("string length %zu\n", string_length); printf ("size_t max value %zu\n", SIZE_MAX); printf ("int max value %d\n", INT_MAX); char* my_string = malloc(string_length+1); char* dest = malloc(string_length+1); // init with non zero to show effect, no trailing nul byte dest[0] = '\0'; for (size_t i = 1; i < string_length+1; ++i) { dest[i] = 'X'; } for (size_t i = 0; i < string_length; ++i) { my_string[i] = 'a'; } my_string[string_length] = '\0'; FILE *fh = fopen("original.txt", "w"); fprintf (fh, "%s", my_string); fclose (fh); wutz_strcpy (dest, my_string); free(my_string); fh = fopen ("wutz_error.txt", "w"); fprintf(fh, "%s", dest); fclose (fh); free(dest); return EXIT_SUCCESS; }
Du hast Pointerarithmetik nicht verstanden
Das sagt der richtige!
-
@Wutz sagte in Frage zu Typedef:
Und deshalb ist der Gebrauch des Standard-Terms "UB" hier sinnfrei
Dein Problem ist, dass du so wenig Ahnung hast, dass du das Problem und UB schon nicht mehr erkennen kannst.
-
@john-0 sagte in Frage zu Typedef:
int ist auf modernen Betriebssystemen ein 32Bit Datentyp unabhängig davon, ob man sich im 32Bit oder 64Bit Modus befindet. size_t expandiert je nach Modus in 32Bit oder 64Bit, passend zur Zeigergröße und den maximalen Feldgrößen.
Davon steht im Standard nichts.
Und du gebrauchst gleichzeitig Standard-Vokabeln, d.h. du hast nichts verstanden; und hier nochmal für solche Begriffsstutzige wie dich:
der Standard legt fest: "auf allen Betriebssystemen... gilt..."
Solche Deppen wie du kommen und gehen, in den letzten 10 Jahren habe ich hier sowas mehrfach gehabt, das geht vorbei.
-
@Wutz sagte in Frage zu Typedef:
Davon steht im Standard nichts.
Doch, das steht da drin. Du musst ihn nur endlich mal vollständig lesen und verstehen. D.h. die Norm garantiert nur für
size_t
, dass man in jeder beliebigen Implementation über Felder (Nachtrag:) vollständig iterieren kann. Fürint
ist das nicht garantiert, es kann funktionieren, wenn die Felder hinreichend klein sind, aber gerade solcher Dreckscode sollte bei einem Codereview eliminiert werden.Ein real existierendes Beispiel habe ich hier gepostet, aber deine Arroganz hindert dich daran es zu verstehen.
Nachtrag: Mein Beispiel zeigt gerade, dass der grobe Unfug, den du die ganze Zeit behauptest eben nicht auf allen Betriebssystemen erfüllt ist. Nutzt man
size_t
in der Funktionwutz_strcpy
funktioniert sie immer auf jeder Plattform unabhängig davon, welches Programmiermodell genutzt wird (16Bit, 32Bit oder 64Bit).