Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.50/26: Рейтинг темы: голосов - 26, средняя оценка - 4.50
 Аватар для Chainyk
15 / 15 / 2
Регистрация: 24.08.2010
Сообщений: 94

Компилятор влияет на результат!!!

03.12.2010, 23:34. Показов 5075. Ответов 27
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Есть такая программа:
C++
1
2
3
4
5
6
7
int _tmain(int argc, _TCHAR* argv[])
{
        const long l = 10;
        *((long*)&l) = 200;
        printf ("%d", l);
        return 0;
}
По умолчанию компилируеться как С++ и выводит 10, но когда правой кнопкой кликнуть по проекту и изменить в свойствах настройки компиляции как чистый С, тогда выводит 200. Подскажите почему?
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
03.12.2010, 23:34
Ответы с готовыми решениями:

Компилятор при делении больших чисел выдает не верный результат
Здравствуйте. Я только осваиваю азы программирования на С++. Компилятор используется g++ Нужно сделать задачу по контрольной сумме...

Компилятор (Visual C++ 6.0) в плохой совместимости с Windows 7. Посоветуйте другой компилятор
Здравствуйте! Я недавно начал заниматься С++, но мой компилятор (Visual C++ 6.0) в плохой совместимости с Windows 7 Посоветуйте какой...

LEFT JOIN странно влияет на результат запроса
Вопрос скорее теоретического характера. Есть 2 таблицы, связанные через 4 поля-ключа. В каждой по миллиону записей примерно. Когда я...

27
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
03.12.2010, 23:40
это нарушение стандарта в обоих случаях и компилятор может делать что угодно, ибо его поведение не определено
1
 Аватар для Chainyk
15 / 15 / 2
Регистрация: 24.08.2010
Сообщений: 94
03.12.2010, 23:45  [ТС]
Ето обход стандартов. Етих фокусов стандарт не запретит. Вопрос не в стандарте, а почему результат иной. Понятно что сделал такой изврат я не случайно
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
03.12.2010, 23:50
Дык, когда UB, компилятор волен делать так, как ему заблагорассудится.

Это как знаменитый, но не столь явный UB:
C++
1
2
3
i=0;
i += i++ + i++
// чему равно i?
Стандарт не запретит, а вот заказчик софта будет очень недоволен. )
1
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
03.12.2010, 23:51
видимо в одном случае компилятор помещяает переменную в защищенную от записи область памяти, а в другом случае нет
1
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
04.12.2010, 00:07
Помнится, в паскакале константы вообще не имели адреса в памяти...
1
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
04.12.2010, 00:08
нене, все в памяти, часть памяти причем защищена на уровне операционной системы
1
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
04.12.2010, 01:54
Короче, создаём такой экзешник

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include <stdio.h> 
#include <Windows.h> 
#include <Winnt.h> 
//Здесь определена структура PROCESSENTRY32 и функция CreateToolhelp32Snapshot
#include <tlhelp32.h>
//int main ();
 FILE *f;
HANDLE HandleProcessa ()  {
 
 HANDLE hProcessSnap;
 PROCESSENTRY32 pe32;
 
 //Это мы находим дескриптор снимка процессов
 hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
 if (hProcessSnap == INVALID_HANDLE_VALUE)
 return false;
 pe32.dwSize = sizeof(PROCESSENTRY32);
 
 
 int i= 0;
 
 while (Process32Next(hProcessSnap, &pe32)) {
//  printf ("%d  %s\n",++i,  pe32.szExeFile);
  fprintf(f,"%s \n",pe32.szExeFile);
 } 
 printf("+++++++++\n");
 fprintf(f,"+++++++++\n");
 
 
 CloseHandle(hProcessSnap);
 
 
}
 int main () {
// FILE *f;
// f = fopen("rezultat.cc","wb");
//  printf ("ppppppppppppp\n");
 f = fopen("rezultat.cc","wb");
  while (1) {
  HandleProcessa ();
  }
 fclose (f);
// fclose (f);
  getchar ();
  return 0;
 }

ПОтом выключаем в оси всякие процессы типа аськи и прочее и быстро шевелим пальцами. Запускаем этот экзешник. ОН создаст текстовый файл с процессами, циклом. ПОсле чего в командной строке набираем
gcc.exe ra.c <Enter>
где gcc.exe это компилятор, необходимо предварительно позаботиться, чтобы ось его нашла (переменная PATH), а ra.c- исходник. с текстом в первом посте

Как только компиляция заканчивается, смотрим получившийся текстовый файл. За эти несколько секунд у меня, например создалось там несколько сот тыщ строк. Это списки процессов оси. Где-то во второй половине список будет выглядеть так:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
[System Process] 
System 
smss.exe 
csrss.exe 
winlogon.exe 
services.exe 
lsass.exe 
svchost.exe 
svchost.exe 
svchost.exe 
svchost.exe 
svchost.exe 
spoolsv.exe 
explorer.exe 
rundll32.exe 
soundman.exe 
avp.exe 
UnlockerAssistant.exe 
punto.exe 
avp.exe 
sqlservr.exe 
nvsvc32.exe 
sqlwriter.exe 
alg.exe 
wuauclt.exe 
firefox.exe 
klwtblfs.exe 
plugin-container.exe 
devcpp.exe 
cmd.exe 
cmd.exe 
main.exe 
gcc.exe
И так раз несколько

А потом он изменится, появится ещё один процесс, дочерний для gcc.exe и список будет выглядеть какое-то время так:

[System Process]
System
smss.exe
csrss.exe
winlogon.exe
services.exe
lsass.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
svchost.exe
spoolsv.exe
explorer.exe
rundll32.exe
soundman.exe
avp.exe
UnlockerAssistant.exe
punto.exe
avp.exe
sqlservr.exe
nvsvc32.exe
sqlwriter.exe
alg.exe
wuauclt.exe
firefox.exe
klwtblfs.exe
plugin-container.exe
devcpp.exe
cmd.exe
cmd.exe
main.exe
gcc.exe
cc1.exe


А теперь если мы всю эту херь проделаем, но изменим имя исходника на *cpp, то имя дочернего процесса будет
cc1plus.exe

ВЫвод: по запуску gcc.exe анализирует строку-имя файла и включает разные процессы. Те, в свою очередь могут ещё какие-то процессы подключать и так далее. если охота проанализируйте списки процессов. Я же показал очевидное: компиляция происходит ПО-РАЗНОМУ. Нечего и удивляться результату. ПРивет.
1
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
04.12.2010, 02:15
ойлоло, *.cpp компилится с++ным компилятором, *.с - сишным (КО)
об этом упоминает еще сам автор, сам этот факт мало говорит о сути вопроса, почему компиляторы ведут себя по-разному, хотя ответ был - в данной ситуации они ведут себя как хотят, ибо правильное поведение не установлено

но тащемто спасибо, поржал

Добавлено через 4 минуты
Chainyk, для полноты ощущений сделайте так:

C++
1
2
3
4
5
6
7
8
const long l = 10;
 
int _tmain(int argc, _TCHAR* argv[])
{
                *((long*)&l) = 200;
                printf ("%d", l);
        return 0;
}
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
04.12.2010, 02:27
Правильно ли я понял, что на вопрос "почему при компиляции С++ и С получаются программы, ведущие себя по-разному" был получен ответ "потому что они компилируются разными компиляторами"?

Настоящие программисты дают совершенно верные, но несколько бессмысленные ответы...
0
Эксперт С++
 Аватар для fasked
5045 / 2624 / 241
Регистрация: 07.10.2009
Сообщений: 4,310
Записей в блоге: 5
04.12.2010, 02:41
Цитата Сообщение от lemegeton Посмотреть сообщение
Настоящие программисты дают совершенно верные, но несколько бессмысленные ответы...
Ответ был в том, что это UB.
0
быдлокодер
 Аватар для kravam
1724 / 911 / 106
Регистрация: 04.06.2008
Сообщений: 5,705
04.12.2010, 08:17
Цитата Сообщение от fasked Посмотреть сообщение
Ответ был в том, что это UB.
а это смотря кто отвечает

Я отвечаю так: в моей среде сначала ни компилируются одним компилятором gcc.exe. А вот он ведёт себя по-разному в зависимости от расширения файла (порождает разные процессы, а, следовательно ожидаем РАЗНЫЙ конечный результат), в чём каждый желающий может убедиться, прежде ознакомившись с моим постом от 01.54 Главное не лениться. Лучше один раз увидеть, чем 7 раз услышать. Впрочем, последнее к некоторым снобам не относится, а относится к добросовестным трудолюбивым парням. Привет.
1
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.12.2010, 09:31
Цитата Сообщение от lemegeton Посмотреть сообщение
Помнится, в паскакале константы вообще не имели адреса в памяти...
Цитата Сообщение от alex_x_x Посмотреть сообщение
нене, все в памяти, часть памяти причем защищена на уровне операционной системы
А вот Эккель ("Философия С++") говорит, что константы (кроме строк) при компиляции заносятся в таблицу имен, т.е. можно сказать как define'ы.
0
481 / 119 / 17
Регистрация: 30.09.2010
Сообщений: 473
04.12.2010, 11:39
Цитата Сообщение от lemegeton Посмотреть сообщение
Помнится, в паскакале константы вообще не имели адреса в памяти...
В Паскале (по крайней мере, в Турбо Паскале и совместимых) есть два типа констант - обычные, являющиеся аналогом
C
1
#define N 100
, и т.н. типизированные, по сути - инициализированные переменные. Под последние память, естественно, выделяется. Под строковые константы память выделяется полюбас.

Добавлено через 3 минуты
Хм... А под константы C++ простых типов память типа const size_t n = 100; память разьве выделяется? Я всегда думал, что от идентификатора типа зависит только, будет ли присваивание константы транслироваться в
Assembler
1
mov ax, 100d
или
Assembler
1
mov eax, 100d
и т.п.
0
 Аватар для lemegeton
4903 / 2696 / 921
Регистрация: 29.11.2010
Сообщений: 5,783
04.12.2010, 11:50
Обратимся к книге. Бьерн Страуструп, "Язык программирования С++".
Раздел 2.5. Поименованные константы.
Описывая какой-либо объект как const, мы гарантируем,
что его значение не изменяется в области видимости
Отметим, что спецификация const скорее ограничивает возможности
использования объекта, чем указывает, где следует размещать объект.
Вообще говоря, транслятор может воспользоваться тем фактом, что объект
является const, для различных целей (конечно, это зависит от
"разумности" транслятора). Самое очевидное - это то, что для
константы не нужно отводить память, поскольку ее значение известно
транслятору. Далее, инициализатор для константы, как правило (но не
всегда) является постоянным выражением, которое можно вычислить на
этапе трансляции. Однако, для массива констант обычно приходится
отводить память, поскольку в общем случае транслятор не знает,
какой элемент массива используется в выражении. Но и в этом случае
на многих машинах возможна оптимизация, если поместить такой массив
в защищенную от записи память.
Так что компилятор решает, как будет реализована поименованная константа. Однозначный UB.
0
 Аватар для Kastaneda
5232 / 3205 / 362
Регистрация: 12.12.2009
Сообщений: 8,143
Записей в блоге: 2
04.12.2010, 12:23
ИМХО
для такого:
C++
1
2
3
4
5
6
#include<iostream>
const int N=10;
int main(){
   char array[N];
.........
}
память выделена не будет.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
04.12.2010, 14:24
То, что запускаются разные компиляторы (а точнее, трансляторы) для разного типа настроек - ещё ничего не доказывает. Деление на cc1 и cc1plus - чисто техническое. Разработчики могли бы вместо двух компиляторов (трансляторов) сделать один и результат был бы точно таким же.

Ответ на поставленный вопрос единственный - тест некорректный, потому как содержит внутри себя undefined behaviour. Разные компиляторы могут выдать разный результат. И даже один и тот же компилятор может показать разные результаты при работе с оптимизациями и без них. Всё зависит от внутреннего устройства компилятора.

В конкретно данном случае рискну предположить следующее. Стандарт Си++ позволяет const переменные использовать в качестве, например, размерности массива, а потому компилятор Си++ в момент обработки конструкции "const int a = 20;" сразу же запоминает, что значение переменной "a" равно 20, а потом любое обращение к переменной заменяет на константу (а переменную не строит вообще). В языке Си этого нет, а потому компилятор для технической простоты этого не делает
1
 Аватар для Chainyk
15 / 15 / 2
Регистрация: 24.08.2010
Сообщений: 94
05.12.2010, 01:20  [ТС]
Evg, спасибо, очень качественный ответ
0
бжни
 Аватар для alex_x_x
2473 / 1684 / 135
Регистрация: 14.05.2009
Сообщений: 7,162
05.12.2010, 15:14
Цитата Сообщение от Kastaneda Посмотреть сообщение
ИМХО
для такого:
C++
1
2
3
4
5
6
#include<iostream>
const int N=10;
int main(){
   char array[N];
.........
}
память выделена не будет.
C++
1
2
3
4
5
6
7
8
const int l = 10;
 
int main()
{        
                *((int*)&l) = 200;
                printf ("%d", l);
        return 0;
}
Bash
1
Output: 1   Segmentation fault
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
05.12.2010, 15:19
По поводу примера из #19. На современных платформах ГЛОБАЛЬНЫЕ const переменные компилятор складывает в специальную секцию, где на уровне ОС запрещены записи. Именно поэтому тест сломался на исполнении. Скорее всего сломался он в момент записи (т.е. если выкинем printf, то падение будет точно таким же). А вот если переменная локальная, то она положится в стек, где уже нет возможности запретить запись
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
05.12.2010, 15:19
Помогаю со студенческими работами здесь

На результат влияет число, которое в выражении не используется
Нужна помощь. Есть задача на вычисление арифметического выражения. Но на ф-цию косинуса в моем примере почему-то влияет значение y, хотя...

Как так получается, что наблюдатель влияет на результат наблюдения?
Объясните, как так получается, что наблюдатель влияет на результат наблюдения. Как наблюдатель разрушает волновую функцию электрона фактом...

Как четность длины массива влияет на результат рекурсивной функции?
Задание: &quot;Задан динамический массив целых чисел. Данные вводятся с клавиатуры. Подсчитать рекурсивно количество четных значений&quot;....

Как определить, какой параметр в большей степени и насколько влияет на результат
Я знаю, что необходимо использовать корреляцию, но если можно, хотелось бы конкретно понять как это сделать

Каким образом, наличие наблюдателя влияет на результат эксперимента Юнга с двумя щелями?
Каким образом, наличие наблюдателя влияет на результат эксперимента Юнга с двумя щелями?


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
http://iceja.net/ математические сервисы
iceja 20.01.2026
Обновила свой сайт http:/ / iceja. net/ , приделала Fast Fourier Transform экстраполяцию сигналов. Однако предсказывает далеко не каждый сигнал (см ограничения http:/ / iceja. net/ fourier/ docs ). Также. . .
http://iceja.net/ сервер решения полиномов
iceja 18.01.2026
Выкатила http:/ / iceja. net/ сервер решения полиномов (находит действительные корни полиномов методом Штурма). На сайте документация по API, но скажу прямо VPS слабенький и 200 000 полиномов. . .
Расчёт переходных процессов в цепи постоянного тока
igorrr37 16.01.2026
/ * Дана цепь постоянного тока с R, L, C, k(ключ), U, E, J. Программа составляет систему уравнений по 1 и 2 законам Кирхгофа, решает её и находит переходные токи и напряжения на элементах схемы. . . .
Восстановить юзерскрипты Greasemonkey из бэкапа браузера
damix 15.01.2026
Если восстановить из бэкапа профиль Firefox после переустановки винды, то список юзерскриптов в Greasemonkey будет пустым. Но восстановить их можно так. Для этого понадобится консольная утилита. . .
Сукцессия микоризы: основная теория в виде двух уравнений.
anaschu 11.01.2026
https:/ / rutube. ru/ video/ 7a537f578d808e67a3c6fd818a44a5c4/
WordPad для Windows 11
Jel 10.01.2026
WordPad для Windows 11 — это приложение, которое восстанавливает классический текстовый редактор WordPad в операционной системе Windows 11. После того как Microsoft исключила WordPad из. . .
Classic Notepad for Windows 11
Jel 10.01.2026
Old Classic Notepad for Windows 11 Приложение для Windows 11, позволяющее пользователям вернуть классическую версию текстового редактора «Блокнот» из Windows 10. Программа предоставляет более. . .
Почему дизайн решает?
Neotwalker 09.01.2026
В современном мире, где конкуренция за внимание потребителя достигла пика, дизайн становится мощным инструментом для успеха бренда. Это не просто красивый внешний вид продукта или сайта — это. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru