LINUX.ORG.RU

А как работает const ?

 


0

6

Все проверки делает компилятор С++ или переменная располагается в области памяти, защищенной от записи?



Последнее исправление: cetjs2 (всего исправлений: 1)

насколько понимаю, если ты её не объявил глобально, это может быть тупо регистр или immediate значение захардкоженоное в команде процессора

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

Там видео с каким то клоуном, который жует сопли по элементарщине. Конкретно вопрос: могу ли я испортить значение conts T в рантайм?

В случае с int понятно, просто подставляется значение и ответ - нет. А если это сложный объект рамером в 100 мегабайт?

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

Дело не в глобальности, а в том, виден ли фактически ее «адрес» за пределами тр.юнита. Как там код будет выглядеть это вообще никак не связано с констом. Уехать в регистр может что угодно, а чтобы инициализироваться из imm не нужно быть констом.

Ирл гарантий нет, что тру-конст кинет трап по записи, но на всяких микроконтроллерах с например 64Кб рам и 1Мб флешкой - вот там консты могут лежать на ридонли флешке и траповать, афаик. В терминах линкера это секция rodata.

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

Ничего там нет, что ему надо, умник. Ты ивен вопрос по английской не осилить сфорумлировать. Нечего ответить сидел бы молчал.

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

Но есть вызов mprotect() system call sets the access protections for the pages that contain the address range addr through addr + len - 1. Что не дает компиляторы объекты const разместить в нем?

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

SO:

In general const is 100% compiler

I suggest the C++ FQA’s section on const correctness: yosefk.com/c++fqa/const.html

Better read on the FAQ about const-correctnes: parashift.com/c++-faq-lite/const-correctness.html

Мда, онаним опять не смог…

Ты ивен вопрос по английской не осилить сфорумлировать

Ты знаешь что такое ключевые слова?

Нечего ответить сидел бы молчал.

Так зачем пишешь?

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

Вполне возможно, что он их и размещает всегда в rodata, скомпиляй да проверь. Но какая память будет под этой секцией - решает системный линкер при запуске (если речь о более-менее десктопном цп, а не о мк, где прога шьется заранее). То есть у самого конпелятора тут голос совещательный.

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

там в шестой ссылке, во втором комментарии нерелевантные данные я принес, чтобы сделать вид, что не обосралси

Иди уже а.

anonymous
()

Все проверки делает компилятор

Да.

переменная располагается в области памяти, защищенной от записи

Иногда.

Siborgium ★★★★★
()

const это не только ro память, а что более важно - ещё и зелёный свет компилятору на оптимизации. Ну зачем в fn(int *i, const int *p) каждый раз читать из памяти p, ему обещали константность.

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

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

Почему же бред, можно иной fn(const int *i), вот здесь уже будет (например, отдадим указатель куда-то в другую функцию).

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

Где я тут константность обещаю? Могу в другом потоке в x писать, и мне ничего не будет.

int foo(const int* x) {
    return *x;
}

int main() {
    int x = 0;
    int y = foo(&x);
}

А restrict в стандарте С++ нет.

Siborgium ★★★★★
()
Последнее исправление: Siborgium (всего исправлений: 1)

Все проверки делает компилятор С++

так точно

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

Ну вот смотри

void v(const int *i);

void fn(const int*i) {int q = *i; cout << q << '\n'; v(i); q = *i; cout << q << '\n';}
int main() {int i = 2; fn(&i);}

// другой модуль
void v(const int *i) {*const_cast<int*>(i) = 0;}

Очевидно, что компилятор спокойно мог бы вырезать второй q = *i (почему-то clang и gcc этого не делают, но могли бы).

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

Компилятор там тупо q и не делает, но если очень захочется, то наверняка можно нафантазировать нужные условия.

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

Ну всё верно.

В функции fn компилятор может оптимизировать, потому что он передаёт в функцию, которая принимает const, то есть не должна менять значение. Оптимизация есть.

Но внутри функции v оптимизации никакой не будет, от того что принимает функция const int* или int*.

fsb4000 ★★★★★
()

Вроде в стандарте было написано что это зависит от реализации, зачем тебе это, знания о поведении достаточно, нет нужды знания о реализации.

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

const это не только ro память, а что более важно - ещё и зелёный свет компилятору на оптимизации. Ну зачем в fn(int *i, const int *p) каждый раз читать из памяти p, ему обещали константность

Ну и бредятина. От наличия const это никак не зависит

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

Могу в другом потоке в x писать, и мне ничего не будет.

Старый анекдот.

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

почему-то clang и gcc этого не делают, но могли бы

void f1(const int& i) { return f2(const_cast<int&>(i)); }

Не могли.

cppsektant
()

Все проверки делает компилятор С++

Какие проверки?

переменная располагается в области памяти, защищенной от записи?

Причём здесь C++?

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

Вот чтобы было ясно, как примерно думает компилятор:

  1. Ок, есть функция v

  2. Она принимает const int*.

  3. Я не знаю её тело.

  4. Если я передам в неё int, то функция может менять значение через const_cast

  5. Если я передам в неё const int, то функция не может менять значение, иначе будет UB.

  6. В программе нет UB, следовательно функция v, не может менять int

  7. Следовательно можно снова не читать.

Если v, будет inline, то компилятор конечно заного прочитает и выведется 0.

Но если не знает, то рассматривает все случаи и выбирает наихудший, если где-то возникает UB, то всё что связано с UB, считает невозможным.

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

Скорее всего, зависит от реализации, как и всегда.
Вот тебе пример из gcc:

#include <stdio.h>

const int a = 1;

int main(int argc, char *argv[])
{
    const int b = 1;
    int *ap = (int *)&a;
    int *bp = (int *)&b;

    *ap = 2; // <- segfault
    *bp = 2; // <- ok

    printf("%d %d\n", a, b);
    return 0;
}

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

Если я передам в неё int, то функция может менять значение через const_cast
Если я передам в неё const int, то функция не может менять значение, иначе будет UB.

Легитимность снятия const и модификации не зависит от наличия/отсутствия const в параметрах. Определено без const - можно снимать и модифицировать.

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

Ну да, я был не прав. Для меня это стало новостью. UB лишь при снятии константности с объектов, которые были с ней объявлены. Никогда const_cast вообще не применял, говнокод какой-то.

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

Она принимает const int*.

Не, компиляторам насрать на const. Это дерьмо для дошколят - анализ на основе этой херни никто не проводит, да и им можно жопу вытереть даже в рамках языка.

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

зачем тебе это

Чтобы ответить на вопрос, что наличие const не дает никаких гарантий, что объект не будет изменен. Т.е. мне никто не мешает писать в память, где расположен const T.

Lzzz
() автор топика
Ответ на: комментарий от pavlick

Говнокод - любое не-семантическое использование const. Но в основном пишут код дошколята, которые пропаганда рассказала про какой-то const и что им нужно обмазываться.

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

Блин и в чем тут разница? Ведь компилятор когда видит, что пытаются получить адрес const переменной, он не может заменять ее значением?

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

Что не дает компиляторы объекты const разместить в нем?

В нём - это в чём? Срочно перечитывать букварь перед тем как срывать покровы.

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

Что мешает? Есть массив константных объектов, получаю адрес начала массива и пишу с некоторым смещением, константных объект будет испорчен. А если массив лежал бы в ro области, по программа упала с ошибкой.

Lzzz
() автор топика
Ответ на: комментарий от fsb4000

Супершкалярный цпу все равно из кеша читнет и будет дешего.

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

И? Это шиза. Тебе сообщили, что хинты к ссылке/указателю ничего не означают. Ты можешь брать константную ссылку на не-константную память. Это валидное поведение - перечитай букварь.

Никаких ro-областей нет - срочно в школу. Хочешь менять права доступа - меняй. Кто тебе не даёт?

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

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

Нету никаких областей. И никакой mprotect ничего не защищает. Прочитай полностью мануал для домохозяек.

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

Нет. Никакой интел тут непричём. Да и ничего, кроме линукса, не нужно. Это мусор для школоты. За исключением частных, не общих применений. Но мы о них не говорим.

Любой mmu реализован так. Области сдохли как несостоятельное дерьмо. А то, что, возможно, они в каком-то бездарном мусоре до сих пор существует - это ничего не значит.

Если ты не про mmu, то всем насрать. Разговор не об этом и эта почти никому не интересно, примитивно и не представляет какой-либо ценности.

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

Когда ты называешь что-то бездарным мусором, оно от этого не теряет экономической эффективности, и против нее твои слова пустышка. Мы говорим в общем, это лишь ты говоришь в частностях. При этом кукарекая, что речь не только об интелолинуксе. Тем временем поведение в сишке описано и реализовано тоже для общего случая, а не для твоих наколеночных бенчей.

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