Как стать автором
Обновить

Комментарии 4

хм, пойти чтоли eiskaltdcpp проверить, тематика та-же..

Если вкратце, то компилятор имеет полное право удалить вызовы memset, если посчитает их бессмысленными (такое часто происходит, когда буфер очищается в конце операции и более не используется). Удостовериться в том, что компиляторы действительно могут убрать ненужный вызов, можно с помощью проверки аналогичного кода сервисом Compiler Explorer.

Приведенный фрагмент кода не аналогичен. Transmission использует Glib и g_free соответственно. Ни один компилятор не посчитает бессмысленым вызов memset и не уберет его перед вызовом g_free.

code
#include <stdlib.h>
#include <string.h>
#include <glib.h>

typedef void* gpointer;
typedef struct
{
    char* target;
    gpointer thereWereOtherElementsButTheyWereTruncatedForAnExample;
    gpointer builder;
}
MakeMetaUI;

void doSomething(gpointer);
void freeMetaUI(gpointer p)
{
    MakeMetaUI* ui = static_cast<MakeMetaUI*>(p);

    doSomething(ui->builder);
    g_free(ui->target);
    memset(ui, ~0, sizeof(MakeMetaUI));
    g_free(ui);
    
}
g++ `pkg-config --cflags --libs glib-2.0` test.cpp -O2 -masm=intel -S
output
	.file	"test.cpp"
	.intel_syntax noprefix
	.text
	.p2align 4
	.globl	_Z10freeMetaUIPv
	.type	_Z10freeMetaUIPv, @function
_Z10freeMetaUIPv:
.LFB334:
	.cfi_startproc
	endbr64
	push	rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	mov	rbp, rdi
	mov	rdi, QWORD PTR 16[rdi]
	call	_Z11doSomethingPv@PLT
	mov	rdi, QWORD PTR 0[rbp]
	call	g_free@PLT
	mov	QWORD PTR 16[rbp], -1
	pcmpeqd	xmm0, xmm0
	mov	rdi, rbp
	movups	XMMWORD PTR 0[rbp], xmm0
	pop	rbp
	.cfi_def_cfa_offset 8
	jmp	g_free@PLT
	.cfi_endproc
.LFE334:
	.size	_Z10freeMetaUIPv, .-_Z10freeMetaUIPv
	.ident	"GCC: (Ubuntu 10.3.0-1ubuntu1~20.04) 10.3.0"
	.section	.note.GNU-stack,"",@progbits
	.section	.note.gnu.property,"a"
	.align 8
	.long	 1f - 0f
	.long	 4f - 1f
	.long	 5
0:
	.string	 "GNU"
1:
	.align 8
	.long	 0xc0000002
	.long	 3f - 2f
2:
	.long	 0x3
3:
	.align 8
4:
clang++ `pkg-config --cflags --libs glib-2.0` test.cpp -O2 -masm=intel -S
output
	.text
	.intel_syntax noprefix
	.file	"test.cpp"
	.globl	_Z10freeMetaUIPv                # -- Begin function _Z10freeMetaUIPv
	.p2align	4, 0x90
	.type	_Z10freeMetaUIPv,@function
_Z10freeMetaUIPv:                       # @_Z10freeMetaUIPv
	.cfi_startproc
# %bb.0:
	push	rbx
	.cfi_def_cfa_offset 16
	.cfi_offset rbx, -16
	mov	rbx, rdi
	mov	rdi, qword ptr [rdi + 16]
	call	_Z11doSomethingPv
	mov	rdi, qword ptr [rbx]
	call	g_free
	pcmpeqd	xmm0, xmm0
	movdqu	xmmword ptr [rbx], xmm0
	mov	qword ptr [rbx + 16], -1
	mov	rdi, rbx
	pop	rbx
	.cfi_def_cfa_offset 8
	jmp	g_free                          # TAILCALL
.Lfunc_end0:
	.size	_Z10freeMetaUIPv, .Lfunc_end0-_Z10freeMetaUIPv
	.cfi_endproc
                                        # -- End function
	.ident	"Ubuntu clang version 11.1.0-++20210428103817+1fdec59bffc1-1~exp1~20210428204431.166"
	.section	".note.GNU-stack","",@progbits
	.addrsig

Я, возможно, не гуру теории программирования, но пояснения к "Фрагмент N4: неудачное явное приведение типа" меня как-то не удовлетворили. Я так понимаю, автор собирал библиотеки на 64-битной системе, где int имеет размер 32 бита, а size_t размер 64 бита. В этом случае объяснение и решение верное, но разве эра 32-битных ситем закончилась и их нигде и никак не осталось? Может быть это уже можно считать верным для десктопа, но для встраиваемых систем это точно вряд ли. Как я понимаю, на 32-битных ситсемах размер size_t будет те же 32 бита, а тогда ни о каком решении проблемы переполнения речи нет.

НЛО прилетело и опубликовало эту надпись здесь
Зарегистрируйтесь на Хабре , чтобы оставить комментарий