Pelles C forum

C language => Beginner questions => Topic started by: John Z on August 08, 2024, 11:56:15 PM

Title: sizeof operator
Post by: John Z on August 08, 2024, 11:56:15 PM
So wondering -

if
LVCOLUMNW TableCol;       // Make Column struct

then is it better to use
memset(&TableCol, 0, sizeof(TableCol));   // Reset Column

or
memset(&TableCol, 0, sizeof(LVCOLUMNW));   // Reset Column

or
Both are OK to use w/o distinction

?

John Z
Title: Re: sizeof operator
Post by: MrBcx on August 09, 2024, 04:00:30 AM
ChatGPT says this and I agree.

Both options are technically correct and will have the same effect since sizeof(TableCol) and sizeof(LVCOLUMNW) are equivalent.

However, using sizeof(TableCol) is generally preferred because it directly ties the memset operation to the actual variable you're working with. This approach improves code maintainability. If the type of TableCol ever changes, the code will still work correctly without needing to update the memset call.

So, while both are okay, using sizeof(TableCol) is often considered better practice.
Title: Re: sizeof operator
Post by: John Z on August 09, 2024, 04:05:40 AM
Great - Thanks MrBcx!

I was using TableCol but thought I'd ask to be sure.

Appreciate it!

John Z
Title: Re: sizeof operator
Post by: WiiLF23 on August 17, 2024, 06:27:33 AM
I always use this when initializing LVITEMW struct


LVITEMW lvItemFileName;
memset(&lvItemFileName, 0, sizeof(LVITEMW));
...


You can use memset() or LVITEMW lvItemFileName = { 0 }. I prefer memset().
Title: Re: sizeof operator
Post by: MrBcx on August 17, 2024, 04:44:34 PM
Quote from: WiiLF23 on August 17, 2024, 06:27:33 AM
I always use this when initializing LVITEMW struct


LVITEMW lvItemFileName;
memset(&lvItemFileName, 0, sizeof(LVITEMW));
...


You can use memset() or LVITEMW lvItemFileName = { 0 }. I prefer memset().

For simple datatypes (ints, floats, etc), ={0}; works great.

For user-defined types, some compilers may issue warnings, in which case we can explicitly
zero each member using, for example, this approach:     struct MyStruct mstr = { 0, 0, 0.0, 0.0 };
Title: Re: sizeof operator
Post by: TimoVJL on August 17, 2024, 11:15:04 PM
={0};optimizer can generate smaller code, so useful in small code  ;)
Title: Re: sizeof operator
Post by: WiiLF23 on September 28, 2024, 06:26:34 PM
This is more than sufficient


LVITEMW lvi = { 0 };


Unless you are working with a RECT, you dont need to input extra parameters. memset is more than enough.
Title: Re: sizeof operator
Post by: HellOfMice on October 27, 2024, 08:40:15 PM
I have read that using memset is not always generated by the compiler prefer to use RtlZeroMemory


From Pelle's
Fills an object with a value. 
Syntax: void __stosb(unsigned char *dst, unsigned char val, size_t num);
void __stosw(unsigned short *dst, unsigned short val, size_t num);
void __stosd(unsigned long *dst, unsigned long val, size_t num);
void __stosq(unsigned long long *dst, unsigned long long val, size_t num);  (X64 only)

Declared in: <intrin.h>

The __stosb, __stosw, __stosd and __stosq function fills the object at dst with num byte, word, double-word, or quad-word values from val using the X86/X64 instruction REP STOSB, REP STOSW, REP STOSD, or REP STOSQ, respectively.

The __stosb, __stosw, __stosd and __stosq functions are only available as intrinsics.

Returns: Nothing
#code
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlzeromemory
https://learn.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-rtlfillmemory

Title: Re: sizeof operator
Post by: Vortex on October 27, 2024, 09:44:26 PM
Reading \PellesC\Include\win\winnt.h :

#define RtlZeroMemory(Destination,Length) (void)memset((Destination),0,(Length))
Title: Re: sizeof operator
Post by: TimoVJL on October 28, 2024, 07:08:55 AM
optimizer can also replace memset to rep stosb
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int __cdecl main(void)
{
//char b[80] = {0};
char b[80];
memset(b, 63, 80);
b[5] = 0;
printf("size: %d %s\n", sizeof(b), b);
return 0;
}
Title: Re: sizeof operator
Post by: HellOfMice on October 28, 2024, 07:30:23 AM
Vortex, I know that but what I read was that in the form the macro RtlZeroMemory is created the compiler cannot remove or replace it as it can do with memset. If I find the link I post it. memset with its stosb is not very efficient and could be easily replaced with __stosXX macro family


memset(b,63,80) can be replace __stosq((unsigned long long *) b, (unsigned long long) 0x3f3f3f3f, sizeof(b) / sizeof(__int64)) ; just 10 loops rather than 80the compiler sets rcx to 80 / 8, sets 0x3f3f3f3f to rax and creates rep stosq instruction


[0000000140001CDB] 31C0                         xor               eax,eax
[0000000140001CDD] B907000000              mov               ecx,7
[0000000140001CE2] F348AB                      rep stosq         


__stosq((unsigned long long *) &_Lvc,0,sizeof(LVCOLUMN) / 8


Title: Re: sizeof operator
Post by: Vortex on October 28, 2024, 09:56:53 AM
Hi HellOfMice,

It works as you described, here is a quick example :

#include <stdio.h>
#include <intrin.h>

int main(void)
{
char p[]={0,1,2,3,4,5,6,7,0,8,9};
__stosq((unsigned long long *)p, 0x4141414141414141,1);
printf("%s\n",p);
return 0;

}


Examining the assembly code :


    lea     rdi,[rsp+25H]
    mov     rax,4141414141414141H
    mov     ecx,1               
    rep     stosq
Title: Re: sizeof operator
Post by: HellOfMice on October 28, 2024, 10:01:24 AM
Vortex you are an expert, not me


What we said can be applied to memset, memcpy...