Извините, ничего не найдено.

Не расстраивайся! Лучше выпей чайку!
Регистрация
Справка
Календарь

Вернуться   forum.boolean.name > Программирование игр для компьютеров > C++

Результаты опроса: f(const x) ?
постоянно - всё, что передаю по значению, должно быть незименным 0 0%
зависит от ситуации (детали - в посте) 0 0%
никогда - не вижу смысла функции запрещать играться с копиями на стеке 6 100.00%
Голосовавшие: 6. Вы ещё не голосовали в этом опросе

Ответ
 
Опции темы
Старый 27.06.2012, 01:46   #1
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
f(const x)

Часто ли вы дополнительно "защищаете" аргументы функции, делая им каст в const, например:
void Save2File(const char* const FileName);
Гарантируя тем самым, что внутри функции значение переменной изменено не будет (в примере - и адрес, и размещённые по нему данные, но интересует только "защита" адреса).
Отдельно оговорюсь: "защита" именно копируемых данных (передаваемых по значению, а не по ссылке или через указатель), т.е. от изменения которых в вызывающем коде ничего не меняется.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 27.06.2012, 02:07   #2
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: f(const x)

void Save2File(const char* const FileName);
если бы мне платили за килобайты кода - защищал бы
а так это адов бред, имхо.

хотя больше бесит когда по константной ссылке передают всякие инты, чары и флоаты.
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо HolyDel за это полезное сообщение:
impersonalis (27.06.2012), Mr_F_ (27.06.2012)
Старый 27.06.2012, 02:13   #3
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Ответ: f(const x)

Сообщение от HolyDel Посмотреть сообщение
void Save2File(const char* const FileName);
если бы мне платили за килобайты кода - защищал бы
а так это адов бред, имхо.

хотя больше бесит когда по константной ссылке передают всякие инты, чары и флоаты.
Суть: избежать случайного затирания внутри функции.
Ну из серии: скопипастил кусок кода из старой реализации, который оперирует массивом FileName и заодно изменяет адрес, хранимый в указателе (допустим, для той задачи это было адекватно [например, указатель ссылается на последний слеш в переданном имени], а в теперешней - нет) . И бац - ошибка.
Пример синтетический конечно, но, если всё по уму писать, то многое от чего можно отказаться - некоторый контроль (особенно при коллективном программировании) можно возложить на язык.

Не думаю, что часто в реализации вы используете повторно нессылочные аргументы - так чего же их не "закрыть"?

Я не агитирую, я высказываю контраргумент для полноты картины
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 27.06.2012, 02:21   #4
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: f(const x)

И бац - ошибка.
локализованная внутри одной функции

если ставим const - то ставим везде. или некрасиво.

в твоем же примере это было бы как то так:
void Save2File1(const char* const FileName)
{
char buff[255];
strcpy(FileName,buff,strlen(FileName)+1);
...код который ставит слеш в buff
и работает с buff
}
который бы успешно скомпилировался и в новой функции. ты же не думаешь, что типы параметров у них будут разные?
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
impersonalis (27.06.2012)
Старый 27.06.2012, 02:35   #5
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Ответ: f(const x)

Приблизительно понял смесь из memcpy и strcpy, но я же писал - в новой реализации как раз не нужно что либо делать (на запись) с аргументом.
Для адресования можно просто создать новый указатель (массив, напомню, и так константный).
char* sl_ptr=FileName+х;
В то время как в скопированной реализации, бралось имя файла без учёта полного адреса, потому там адекватно использовался "аргументный" указатель:
FileName+=х;
Отсутствие "защиты" (и копипаст!) приведёт к тому, что выбравшийся из леса конструкций указатель уже будет совсем не тем, что прежде. Он по-прежнему будет ласково отзываться на своё прежнее имя, но тьма уже простёрла руку: внутри него имена всемогущей кучи.


Наличие "защиты" какбэ говорит нам: имя файла определено в рамках функции раз и навсегда. Хотите создавать свои сущности - именуйте их иначе.

Ладно: пусть это будет текущее время, переданное в функцию решения группы диф.ур-ий.
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 27.06.2012, 10:26   #6
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: f(const x)

видимо я криво объяснил свою точку зрения. на счет копипаста она довольно проста на самом деле:

1) если у некоторых функций аргумент будет константным а у некоторых нет - то мы выносим детали реализации в интерфейс, а это говно.
2) поэтому, надо или у всех функций делать аргумент константным или у всех не делать
3) если у исходной функциии аргумент константный, то внутри находится код, который эту константность как-то обходит, и этот код будет копипаститься в новую функцию (также с константным аргументом) и успешно будет компилироваться.
4) если же у исходной функции аргумент НЕ константный, а у новой константный - то см пункт 1.
(Offline)
 
Ответить с цитированием
Эти 2 пользователя(ей) сказали Спасибо HolyDel за это полезное сообщение:
impersonalis (27.06.2012), Mr_F_ (27.06.2012)
Старый 27.06.2012, 10:44   #7
impersonalis
Зануда с интернетом
 
Аватар для impersonalis
 
Регистрация: 04.09.2005
Сообщений: 14,014
Написано 6,798 полезных сообщений
(для 20,935 пользователей)
Ответ: f(const x)

Сообщение от HolyDel Посмотреть сообщение
видимо я криво объяснил свою точку зрения. на счет копипаста она довольно проста на самом деле:

1) если у некоторых функций аргумент будет константным а у некоторых нет - то мы выносим детали реализации в интерфейс, а это говно.
2) поэтому, надо или у всех функций делать аргумент константным или у всех не делать
3) если у исходной функциии аргумент константный, то внутри находится код, который эту константность как-то обходит, и этот код будет копипаститься в новую функцию (также с константным аргументом) и успешно будет компилироваться.
4) если же у исходной функции аргумент НЕ константный, а у новой константный - то см пункт 1.
Более чем доходчиво! Стало понятно после первого прочтения.
Остался лишь риторический осадок: может стоит запрещать изменять аргументы функций, передаваемые по значению правилами языка?
__________________
http://nabatchikov.com
Мир нужно делать лучше и чище. Иначе, зачем мы живем? tormoz
А я растила сына на преданьях
о принцах, троллях, потайных свиданьях,
погонях, похищениях невест.
Да кто же знал, что сказка душу съест?
(Offline)
 
Ответить с цитированием
Старый 27.06.2012, 11:03   #8
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: f(const x)

теоретически должно быть полезно.
на практике я куда чаще сталкивался с удобством изменения параметра (было пару раз), чем с ошибками, связанными из - за его не константности (ни разу не сталкивался).

еще можно делать так (по крайней мере в студии ,не знаю насколько это по стандарту) с одной стороны остается чистый интерфейс - с другой, реализация может учитывать константным оставлять аргумент или нет.
const char* x(const char* value); //Интерфейс

const char* x(const char* const value) //реализацяи
{
	value = "begrh"; //ошибка компиляции
	return value;
}
(Offline)
 
Ответить с цитированием
Старый 27.06.2012, 12:46   #9
jimon
 
Сообщений: n/a
Ответ: f(const x)

давайте попробуем заставить llvm ( http://llvm.org/demo/index.cgi ) выдать разный код с const и без, мой пример пока даёт одинаковый код :

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

uintptr_t test1(const int * a)
{
return (uintptr_t)a + 0xff;
}

uintptr_t test2(const int * const a)
{
return (uintptr_t)a + 0xff;
}

int main()
{
int a = 0, b = 0;
printf("%li\n", test1(&a));
printf("%li\n", test2(&b));
}
и выхлоп :

; ModuleID = '/tmp/webcompile/_10893_0.bc'
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

@.str = private unnamed_addr constant [5 x i8] c"%li\0A\00", align 1

define i64 @test1(i32* %a) nounwind uwtable readnone {
  %1 = ptrtoint i32* %a to i64
  %2 = add i64 %1, 255
  ret i64 %2
}

define i64 @test2(i32* %a) nounwind uwtable readnone {
  %1 = ptrtoint i32* %a to i64
  %2 = add i64 %1, 255
  ret i64 %2
}

define i32 @main() nounwind uwtable {
  %a = alloca i32, align 4
  %b = alloca i32, align 4
  store i32 0, i32* %a, align 4, !tbaa !0
  store i32 0, i32* %b, align 4, !tbaa !0
  %1 = ptrtoint i32* %a to i64
  %2 = add i64 %1, 255
  %3 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i64 0, i64 0), i64 %2) nounwind
  %4 = ptrtoint i32* %b to i64
  %5 = add i64 %4, 255
  %6 = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([5 x i8]* @.str, i64 0, i64 0), i64 %5) nounwind
  ret i32 0
}

declare i32 @printf(i8* nocapture, ...) nounwind
кодогенератор в x64 вообще интересно свернул llvm ассемблер :
.file	"/tmp/webcompile/_11162_0.bc"
	.text
	.globl	test1
	.align	16, 0x90
	.type	test1,@function
test1:                                  # @test1
.Ltmp0:
	.cfi_startproc
# BB#0:
	leaq	255(%rdi), %rax
	ret
.Ltmp1:
	.size	test1, .Ltmp1-test1
.Ltmp2:
	.cfi_endproc
.Leh_func_end0:

	.globl	test2
	.align	16, 0x90
	.type	test2,@function
test2:                                  # @test2
.Ltmp3:
	.cfi_startproc
# BB#0:
	leaq	255(%rdi), %rax
	ret
.Ltmp4:
	.size	test2, .Ltmp4-test2
.Ltmp5:
	.cfi_endproc
.Leh_func_end1:

	.globl	main
	.align	16, 0x90
	.type	main,@function
main:                                   # @main
.Ltmp7:
	.cfi_startproc
# BB#0:
	pushq	%rax
.Ltmp8:
	.cfi_def_cfa_offset 16
	movl	$0, 4(%rsp)
	movl	$0, (%rsp)
	leaq	259(%rsp), %rsi
	movl	$.L.str, %edi
	xorb	%al, %al
	callq	printf
	leaq	255(%rsp), %rsi
	movl	$.L.str, %edi
	xorb	%al, %al
	callq	printf
	xorl	%eax, %eax
	popq	%rdx
	ret
.Ltmp9:
	.size	main, .Ltmp9-main
.Ltmp10:
	.cfi_endproc
.Leh_func_end2:

	.type	.L.str,@object          # @.str
	.section	.rodata.str1.1,"aMS",@progbits,1
.L.str:
	.asciz	 "%li\n"
	.size	.L.str, 5


	.section	".note.GNU-stack","",@progbits
функции в две команды
 
Ответить с цитированием
Старый 27.06.2012, 13:14   #10
HolyDel
 
Регистрация: 26.09.2006
Сообщений: 6,035
Написано 1,474 полезных сообщений
(для 2,707 пользователей)
Ответ: f(const x)

выдать разный код с const и без
при чем здесь это?
Импер предлагал использовать const для обнаружения возможных ошибок на этапе компиляции, а не для оптимизации исполнимого кода
(Offline)
 
Ответить с цитированием
Старый 27.06.2012, 15:04   #11
ffinder
Дэвелопер
 
Аватар для ffinder
 
Регистрация: 10.09.2007
Сообщений: 1,442
Написано 793 полезных сообщений
(для 1,460 пользователей)
Ответ: f(const x)

импэ, переходи уже на функциональные языки - там много матана, теорката и главное (!) все переменные - неизменяемые.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Randomize (27.06.2012)
Старый 27.06.2012, 22:21   #12
Randomize
[object Object]
 
Аватар для Randomize
 
Регистрация: 01.08.2008
Адрес: В России
Сообщений: 4,355
Написано 2,471 полезных сообщений
(для 6,853 пользователей)
Ответ: f(const x)

Сообщение от ffinder Посмотреть сообщение
переменные - неизменяемые
какие же они тогда "переменные"?
__________________
Retry, Abort, Ignore? █
Intel Core i7-9700 4.70 Ghz; 64Gb; Nvidia RTX 3070
AMD Ryzen 7 3800X 4.3Ghz; 64Gb; Nvidia 1070Ti
AMD Ryzen 7 1700X 3.4Ghz; 8Gb; AMD RX 570
AMD Athlon II 2.6Ghz; 8Gb; Nvidia GTX 750 Ti
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
impersonalis (27.06.2012)
Старый 28.06.2012, 00:18   #13
ffinder
Дэвелопер
 
Аватар для ffinder
 
Регистрация: 10.09.2007
Сообщений: 1,442
Написано 793 полезных сообщений
(для 1,460 пользователей)
Ответ: f(const x)

Сообщение от Randomize Посмотреть сообщение
какие же они тогда "переменные"?
еще один пример legacy. они - значения, которые передаются в качестве параметров функций.
но! в математике переменные вовсе не меняют своих значений.
(Offline)
 
Ответить с цитированием
Сообщение было полезно следующим пользователям:
Randomize (28.06.2012)
Ответ


Опции темы

Ваши права в разделе
Вы не можете создавать темы
Вы не можете отвечать на сообщения
Вы не можете прикреплять файлы
Вы не можете редактировать сообщения

BB коды Вкл.
Смайлы Вкл.
[IMG] код Вкл.
HTML код Выкл.


Часовой пояс GMT +4, время: 04:19.


vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot
Style crйe par Allan - vBulletin-Ressources.com