Форум программистов, компьютерный форум CyberForum.ru

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

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 12, средняя оценка - 4.67
Chainyk
 Аватар для Chainyk
15 / 15 / 1
Регистрация: 24.08.2010
Сообщений: 94
03.12.2010, 23:34     Компилятор влияет на результат!!! #1
Есть такая программа:
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. Подскажите почему?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
03.12.2010, 23:40     Компилятор влияет на результат!!! #2
это нарушение стандарта в обоих случаях и компилятор может делать что угодно, ибо его поведение не определено
Chainyk
 Аватар для Chainyk
15 / 15 / 1
Регистрация: 24.08.2010
Сообщений: 94
03.12.2010, 23:45  [ТС]     Компилятор влияет на результат!!! #3
Ето обход стандартов. Етих фокусов стандарт не запретит. Вопрос не в стандарте, а почему результат иной. Понятно что сделал такой изврат я не случайно
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
03.12.2010, 23:50     Компилятор влияет на результат!!! #4
Дык, когда UB, компилятор волен делать так, как ему заблагорассудится.

Это как знаменитый, но не столь явный UB:
C++
1
2
3
i=0;
i += i++ + i++
// чему равно i?
Стандарт не запретит, а вот заказчик софта будет очень недоволен. )
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
03.12.2010, 23:51     Компилятор влияет на результат!!! #5
видимо в одном случае компилятор помещяает переменную в защищенную от записи область памяти, а в другом случае нет
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
04.12.2010, 00:07     Компилятор влияет на результат!!! #6
Помнится, в паскакале константы вообще не имели адреса в памяти...
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
04.12.2010, 00:08     Компилятор влияет на результат!!! #7
нене, все в памяти, часть памяти причем защищена на уровне операционной системы
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
04.12.2010, 01:54     Компилятор влияет на результат!!! #8
Короче, создаём такой экзешник

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 анализирует строку-имя файла и включает разные процессы. Те, в свою очередь могут ещё какие-то процессы подключать и так далее. если охота проанализируйте списки процессов. Я же показал очевидное: компиляция происходит ПО-РАЗНОМУ. Нечего и удивляться результату. ПРивет.
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
04.12.2010, 02:15     Компилятор влияет на результат!!! #9
ойлоло, *.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;
}
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
04.12.2010, 02:27     Компилятор влияет на результат!!! #10
Правильно ли я понял, что на вопрос "почему при компиляции С++ и С получаются программы, ведущие себя по-разному" был получен ответ "потому что они компилируются разными компиляторами"?

Настоящие программисты дают совершенно верные, но несколько бессмысленные ответы...
fasked
Эксперт C++
 Аватар для fasked
4924 / 2504 / 180
Регистрация: 07.10.2009
Сообщений: 4,306
Записей в блоге: 1
04.12.2010, 02:41     Компилятор влияет на результат!!! #11
Цитата Сообщение от lemegeton Посмотреть сообщение
Настоящие программисты дают совершенно верные, но несколько бессмысленные ответы...
Ответ был в том, что это UB.
kravam
быдлокодер
 Аватар для kravam
1512 / 872 / 44
Регистрация: 04.06.2008
Сообщений: 5,271
04.12.2010, 08:17     Компилятор влияет на результат!!! #12
Цитата Сообщение от fasked Посмотреть сообщение
Ответ был в том, что это UB.
а это смотря кто отвечает

Я отвечаю так: в моей среде сначала ни компилируются одним компилятором gcc.exe. А вот он ведёт себя по-разному в зависимости от расширения файла (порождает разные процессы, а, следовательно ожидаем РАЗНЫЙ конечный результат), в чём каждый желающий может убедиться, прежде ознакомившись с моим постом от 01.54 Главное не лениться. Лучше один раз увидеть, чем 7 раз услышать. Впрочем, последнее к некоторым снобам не относится, а относится к добросовестным трудолюбивым парням. Привет.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
04.12.2010, 09:31     Компилятор влияет на результат!!! #13
Цитата Сообщение от lemegeton Посмотреть сообщение
Помнится, в паскакале константы вообще не имели адреса в памяти...
Цитата Сообщение от alex_x_x Посмотреть сообщение
нене, все в памяти, часть памяти причем защищена на уровне операционной системы
А вот Эккель ("Философия С++") говорит, что константы (кроме строк) при компиляции заносятся в таблицу имен, т.е. можно сказать как define'ы.
Напильнег
480 / 120 / 10
Регистрация: 30.09.2010
Сообщений: 473
04.12.2010, 11:39     Компилятор влияет на результат!!! #14
Цитата Сообщение от lemegeton Посмотреть сообщение
Помнится, в паскакале константы вообще не имели адреса в памяти...
В Паскале (по крайней мере, в Турбо Паскале и совместимых) есть два типа констант - обычные, являющиеся аналогом
C
1
#define N 100
, и т.н. типизированные, по сути - инициализированные переменные. Под последние память, естественно, выделяется. Под строковые константы память выделяется полюбас.

Добавлено через 3 минуты
Хм... А под константы C++ простых типов память типа const size_t n = 100; память разьве выделяется? Я всегда думал, что от идентификатора типа зависит только, будет ли присваивание константы транслироваться в
Assembler
1
mov ax, 100d
или
Assembler
1
mov eax, 100d
и т.п.
lemegeton
 Аватар для lemegeton
2909 / 1338 / 133
Регистрация: 29.11.2010
Сообщений: 2,720
04.12.2010, 11:50     Компилятор влияет на результат!!! #15
Обратимся к книге. Бьерн Страуструп, "Язык программирования С++".
Раздел 2.5. Поименованные константы.
Описывая какой-либо объект как const, мы гарантируем,
что его значение не изменяется в области видимости
Отметим, что спецификация const скорее ограничивает возможности
использования объекта, чем указывает, где следует размещать объект.
Вообще говоря, транслятор может воспользоваться тем фактом, что объект
является const, для различных целей (конечно, это зависит от
"разумности" транслятора). Самое очевидное - это то, что для
константы не нужно отводить память, поскольку ее значение известно
транслятору. Далее, инициализатор для константы, как правило (но не
всегда) является постоянным выражением, которое можно вычислить на
этапе трансляции. Однако, для массива констант обычно приходится
отводить память, поскольку в общем случае транслятор не знает,
какой элемент массива используется в выражении. Но и в этом случае
на многих машинах возможна оптимизация, если поместить такой массив
в защищенную от записи память.
Так что компилятор решает, как будет реализована поименованная константа. Однозначный UB.
Kastaneda
Модератор
Эксперт С++
 Аватар для Kastaneda
4236 / 2769 / 218
Регистрация: 12.12.2009
Сообщений: 7,104
Записей в блоге: 1
Завершенные тесты: 1
04.12.2010, 12:23     Компилятор влияет на результат!!! #16
ИМХО
для такого:
C++
1
2
3
4
5
6
#include<iostream>
const int N=10;
int main(){
   char array[N];
.........
}
память выделена не будет.
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
04.12.2010, 14:24     Компилятор влияет на результат!!! #17
То, что запускаются разные компиляторы (а точнее, трансляторы) для разного типа настроек - ещё ничего не доказывает. Деление на cc1 и cc1plus - чисто техническое. Разработчики могли бы вместо двух компиляторов (трансляторов) сделать один и результат был бы точно таким же.

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

В конкретно данном случае рискну предположить следующее. Стандарт Си++ позволяет const переменные использовать в качестве, например, размерности массива, а потому компилятор Си++ в момент обработки конструкции "const int a = 20;" сразу же запоминает, что значение переменной "a" равно 20, а потом любое обращение к переменной заменяет на константу (а переменную не строит вообще). В языке Си этого нет, а потому компилятор для технической простоты этого не делает
Chainyk
 Аватар для Chainyk
15 / 15 / 1
Регистрация: 24.08.2010
Сообщений: 94
05.12.2010, 01:20  [ТС]     Компилятор влияет на результат!!! #18
Evg, спасибо, очень качественный ответ
alex_x_x
бжни
 Аватар для alex_x_x
2441 / 1646 / 84
Регистрация: 14.05.2009
Сообщений: 7,163
05.12.2010, 15:14     Компилятор влияет на результат!!! #19
Цитата Сообщение от 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
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
05.12.2010, 15:19     Компилятор влияет на результат!!!
Еще ссылки по теме:

Родительский класс неявно влияет на значение переменной наследника C++
Параметр конструктора класса нигде не задействован, но его отсутствие влияет на компиляцию, почему так? C++
C++ Локальная переменная влияет на отображение глобальной, что делать?

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

Или воспользуйтесь поиском по форуму:
Evg
Эксперт С++Автор FAQ
 Аватар для Evg
16825 / 5246 / 321
Регистрация: 30.03.2009
Сообщений: 14,127
Записей в блоге: 26
05.12.2010, 15:19     Компилятор влияет на результат!!! #20
По поводу примера из #19. На современных платформах ГЛОБАЛЬНЫЕ const переменные компилятор складывает в специальную секцию, где на уровне ОС запрещены записи. Именно поэтому тест сломался на исполнении. Скорее всего сломался он в момент записи (т.е. если выкинем printf, то падение будет точно таким же). А вот если переменная локальная, то она положится в стек, где уже нет возможности запретить запись
Yandex
Объявления
05.12.2010, 15:19     Компилятор влияет на результат!!!
Ответ Создать тему
Опции темы

Текущее время: 17:14. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru