Autor Thema: memset();  (Gelesen 4260 mal)

nnosdev

  • Beiträge: 61
    • Profil anzeigen
Gespeichert
« am: 24. March 2012, 23:05 »
Da ich mir nicht ganz sicher bin, ob man dieser Funktion vertrauen kann wollte ich
hier mal nachfragen.. Simuliert wird auf einem 32-Bit i386er.

void* memset(void *ptr, uint32 value, size_t bytes)
{
if(bytes < 1)
return 0;

uint32 *pt = (uint32*) ptr;

// Last two bytes are going to be lost after the bit shift
uint32 carry = bytes & 0x3;

// Integer division by 4
bytes >>= 2;

while(bytes) {
*pt = value;
pt++;
bytes--;
}

if(carry) {
pt++;
*pt = value;
}

return ptr;
}

Kann man dieser Funktion vertrauen? ^^

XanClic

  • Beiträge: 261
    • Profil anzeigen
    • github
Gespeichert
« Antwort #1 am: 24. March 2012, 23:22 »
Nö, erstes müsste es in der ersten while-Schleife
*pt = (value << 24) | (value << 16) | (value << 8) | value;heißen (oder ähnlich) und zweitens müsste das letzte if da noch eine Schleife sein, so ist es ziemlich falsch, aber das ist der Inhalt des ifs selbst auch. Sinnvoller wäre vielleicht
uint8 *bpt = (uint8 *)pt;
while (carry--)
    *(bpt++) = value;

Prinzipiell spricht aber nichts dagegen, den ganz naiven Ansatz zu gehen:
void *memset(void *ptr, uint32 value, size_t bytes)
{
    uint8 *pt = ptr;
    while (bytes--)
        *(pt++) = value;
    return ptr;
}

In der Annahme, dass du ein einigermaßen standardkonformes memset schreiben willst, das eben byteweise arbeitet und in der weiteren Annahme, dass deine uintXX-Typen den normalen uintXX_t-Typen entsprechen.

nnosdev

  • Beiträge: 61
    • Profil anzeigen
Gespeichert
« Antwort #2 am: 24. March 2012, 23:38 »
Hallo XanClic,

danke für die Antwort!

Also nach meinem Post hab ich mir eben gedacht, dass es wohl sinnvoller wäre,
jedes Byte einzeln zu setzen. Im Grunde sieht meine Funktion jetzt aus
wie die von dir gepostete.
Würdest du mir diese Implementierung empfehlen oder lieber eine andere?


Prinzipiell spricht aber nichts dagegen, den ganz naiven Ansatz zu gehen:
void *memset(void *ptr, uint32 value, size_t bytes)
{
    uint8 *pt = ptr;
    while (bytes--)
        *(pt++) = value;
    return ptr;
}

In der Annahme, dass du ein einigermaßen standardkonformes memset schreiben willst, das eben byteweise arbeitet und in der weiteren Annahme, dass deine uintXX-Typen den normalen uintXX_t-Typen entsprechen.

Ad uintXX_t-Typen: Wofür steht eigentlich der Zusatz "_t"


XanClic

  • Beiträge: 261
    • Profil anzeigen
    • github
Gespeichert
« Antwort #3 am: 25. March 2012, 03:04 »
Ich würde dir auf jeden Fall die Implementierung empfehlen, da heutige C-Compiler gut genug sind, das ziemlich stark zu optimieren (ich denke, gcc erkennt da direkt, dass das ein memset werden soll und packt seinen eigenen Code rein, weiß ich aber nicht genau).

Bei den Typen… Pfiua. Ich denke mal, es steht für „type“ oder „typedef“. Macht man zumindest häufiger, dass an Typen von typedefs ein _t rankommt, bei mir ist es also mehr oder weniger Gruppenzwang. :wink:

nnosdev

  • Beiträge: 61
    • Profil anzeigen
Gespeichert
« Antwort #4 am: 25. March 2012, 14:05 »
Okay, dann werd ich sie so implementieren :)


:D

Die Frage hab ich mir schon oft gestellt. Wie bei dir wärs bei mir eher der Gruppenzwang als das Wissen darum, weshalb man das so nennt ^^

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #5 am: 25. March 2012, 18:06 »
Bei den Typen… Pfiua. Ich denke mal, es steht für „type“ oder „typedef“. Macht man zumindest häufiger, dass an Typen von typedefs ein _t rankommt, bei mir ist es also mehr oder weniger Gruppenzwang. :wink:
POSIX reserviert sich das übrigens. Wenn du also ein POSIX-konformes Programm schreiben willst, darfst du strenggenommen keine neuen *_t einführen.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

Sannaj

  • Beiträge: 103
    • Profil anzeigen
Gespeichert
« Antwort #6 am: 27. March 2012, 19:34 »
Das "_t". Steht warscheinlich für types. Alle Datentypen, die irgentwo in der cstdlib auftrauchen, und die nicht zu den "echten" C-Datenypen (char,short,long,int,unsigned,signed,float,double,...) gehören, tragen diese Endung.

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #7 am: 28. March 2012, 00:17 »
bool. Widerspruch, q.e.d.  :-D
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #8 am: 28. March 2012, 13:56 »
bool wurde aus C++ übernommen ;)
stell dir vor du müsstest jedes Mal bool_t schreiben  :-o *angst hab'* :D

man müsste also "Alle Datentypen ..." zu "Die meisten Datentypen ..." umbauen

kevin

  • Administrator
  • Beiträge: 2 767
    • Profil anzeigen
Gespeichert
« Antwort #9 am: 28. March 2012, 16:24 »
Ja, nur ist die Aussage dann irgendwie wertlos. ;)

va_list und FILE dürften auch noch als "unechte" Typen durchgehen. Wahrscheinlich gibt es auch noch mehr.
Thou shalt not follow the NULL pointer, for chaos and madness await thee at its end.

LittleFox

  • Beiträge: 306
    • Profil anzeigen
    • LF-Net.org
Gespeichert
« Antwort #10 am: 28. March 2012, 17:58 »
hmm - auch wieder wahr :D

 

Einloggen