LINUX.ORG.RU

Как ты понимаешь, define обрабатывается препроцессором, т.е. вместо макроса на стадии компиляции будет помещено твое число. const же помещает число в секцию text (т.е. если это, например, микроконтроллер, его потом можно будет изменять, перезаписывая флеш).

На ПК разница лишь в том, что define не дает константе тип, что в некоторых случаях может вызывать проблемы.

anonymous
()

константы, константы, константы

tema696
() автор топика

define это директива, если написать #define X Y то компилятор просто заменит во всем тексте символы Х на Y. А что такое X и Y это тебе решать. Это не переменная.

mbivanyuk ★★★★★
()

В C константные переменные не являются константными выражениями и такое не работает:

const int size = 10;
int array[size];

int
main(int argc, char *argv[])
{
}
А с #define или enum сработает.

xaizek ★★★★★
()
Ответ на: комментарий от someoneelsenotme

офигенно, вы сами писали? Если автор решит дописать книгу, с удовольствием прочту

tema696
() автор топика

const означает невозможность изменения, но может быть проинициализирован разными значениями. const нельзя использовать для задания размера статического массива например

mittorn ★★★★★
()
Ответ на: комментарий от post-factum

Это вообще черновик, писал когда был временно безработный, сейчас времени не особо, занят другим пет-проектом. Просто книга - побочка над тьюринг полным macro-based с89-complied проектом. Т.е. весь матан на макросах без ограничений которые есть в бусте, без самого boost и c89-complied.

someoneelsenotme
()
Ответ на: комментарий от xaizek

В C константные переменные не являются константными выражениями и такое не работает:

работает начиная с C99.

waker ★★★★★
()
Ответ на: комментарий от xaizek

ты прав. меня ввел в заблуждение шланг, нарушающий стандарты. сожрал и не подавился.

(но с -Wpedantic выдает warning: size of static array must be an integer constant expression)

waker ★★★★★
()
Последнее исправление: waker (всего исправлений: 1)
Ответ на: комментарий от someoneelsenotme

Интересно было бы однажды увидеть и то и другое :)

mersinvald ★★★★★
()
Ответ на: комментарий от xaizek

В C константные переменные не являются константными выражениями и такое не работает:

А почему тогда в .rodata, если не константные?

% echo 'const int size = 10;

int
main(int argc, char *argv[])
{
}' > tmp/a.c && gcc -S tmp/a.c -o /dev/tty
	.file	"a.c"
	.globl	size
	.section	.rodata
	.align 4
	.type	size, @object
	.size	size, 4
size:
	.long	10
	.text
	.globl	main
	.type	main, @function
main:
.LFB0:
	.cfi_startproc
	pushq	%rbp
	.cfi_def_cfa_offset 16
	.cfi_offset 6, -16
	movq	%rsp, %rbp
	.cfi_def_cfa_register 6
	movl	%edi, -4(%rbp)
	movq	%rsi, -16(%rbp)
	movl	$0, %eax
	popq	%rbp
	.cfi_def_cfa 7, 8
	ret
	.cfi_endproc
.LFE0:
	.size	main, .-main
	.ident	"GCC: (Debian 6.2.1-5) 6.2.1 20161124"
	.section	.note.GNU-stack,"",@progbits

evilface ★★
()
Ответ на: комментарий от evilface

Проще так делать:

echo 'const int size = 10; int main(int argc, char *argv[]) { }' | gcc -x c -S - -o -

А почему тогда в .rodata, если не константные?

Данные то считаются константными, но язык не рассматривает значения переменных как константные выражения. Константы могут быть extern и, видимо, чтобы быть последовательными, все константы считаются условно изменяемыми (может в Rational описывается это решение, не смотрел).

xaizek ★★★★★
()
Ответ на: комментарий от xaizek

Понятно, спасибо. По сути, защита пользователя от случайного изменения и подсказка компилятору о возможных оптимизациях.

evilface ★★
()
Ответ на: комментарий от xaizek

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

На сколько я понимаю, скорее дело в том, что значение может быть в другой единице трансляции. Если в a.c задано const int a = 10;, а в b.c extern const int a; int b[a];, то при компиляции b.c компилятор не будет знать, сколько выделять под b.

deadskif
()

спецификатор const для С - костыль, для C++ некоторая помощь в оптимизации и битие-по-рукам. как-то так примерно :-)

не использование const в C и использование его-же в С++ - одно из различий между языками и программистами на оных

MKuznetsov ★★★★★
()
Ответ на: комментарий от evilface

Это зависит от компилятора. Я цитатну кусочек уже сброшенной главы:

#include <stdio.h>
const int VALUE = 100; 4
int main()
{
      printf("At first I was %d\n", VALUE);
      *(int *)&VALUE = 101;
      printf("But then I was like %d\n", VALUE);
      return 0;
}

Этот код является типичным случаем UB1. Он должен сработать на Borland C++ и Turbo C++ компиляторах, упасть из-за segmentation fault на GCC, попытаться перетереть FLASH на эмбеддед системах, попытаться перетереть .text секцию на MSVC и так далее. Даже GCC на разных уровнях оптимизации выдает разное поведение:

someoneelsenotme
()
Ответ на: комментарий от MKuznetsov

Без этого костыля ты никак в rodata данные не засунешь! И будут они в оперативке болтаться, хотя нафиг это не нужно. А const позволяет легко и просто жирные таблицы (хоть по 16кБ) шрифтов воткнуть в микроконтроллеры с оперативкой в 2кБ!!!

anonymous
()
Ответ на: комментарий от someoneelsenotme

Я знаю, что так можно попытаться сделать и что это UB вне зависимости, в .rodata оно или где. Вопрос был в том, почему оно с точки зрения языка не константно, а не где будет размещено.

evilface ★★
()
Ответ на: комментарий от evilface

Потому что в разных реализациях дело может обстоять по разному. То что тебе конкретный компилятор под конкретную платформу сделал таким образом, не значит, что во всех остальных случаях будет также.

omnomnomnus
()
Ответ на: комментарий от omnomnomnus

Я знаю. Константу можно выкинуть вообще, с -O{2,3} gcc так и сделает, скорее всего. Оставит её в операндах инструкций. Но стандарт учитывает-то не реализации, а самого себя, про что мне и ответили.

evilface ★★
()
Ответ на: комментарий от evilface

Да, невнимательно прочитал, извиняюсь.

В общем выше уже всё ответили.

omnomnomnus
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.