Форум программистов, компьютерный форум, киберфорум
C для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
1

Почему компилируется код?

11.10.2016, 12:03. Показов 1547. Ответов 19
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include  <stdio.h>
 
int main(void)
{
    double d = 1.12;
    f(d);
    f("Hello");
    return 0;
}
 
void f (char arg)
{
    printf("%d", arg);
}
http://rextester.com/WVSP31783

Функция f ожидает char, но никак не double или строковый литерал. Почему не выводятся ошибки?

Добавлено через 1 минуту
И откуда берется значение 171? Его в коде нет
0
Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
11.10.2016, 12:03
Ответы с готовыми решениями:

Не компилируется код
#include &lt;stdio.h&gt; int main() { int i=1; int s=200; int sum=0; while (i&lt;=s) {...

Код не компилируется
#include&lt;stdio.h&gt; #include&lt;math.h&gt; int main() { double a,b,c,x1,x2,d;...

Не компилируется код
Вот прога: #include &lt;stdio.h&gt; struct Element{ // структура, задающая элемент списка ...

Код не компилируется
#include &lt;stdio.h&gt; #include &lt;string.h&gt; #include&lt;conio.h&gt; #include &lt;malloc.h&gt; #include...

19
48 / 46 / 18
Регистрация: 27.04.2016
Сообщений: 169
11.10.2016, 12:24 2
Цитата Сообщение от sys_beginner Посмотреть сообщение
Почему не выводятся ошибки?
Ошибку не выводит, потому что здесь уместно предупреждение, поставьте галочку "Show compiler warnings".
Цитата Сообщение от sys_beginner Посмотреть сообщение
И откуда берется значение 171? Его в коде нет
1 - это 1 из числа 1.21. Откуда берется 71 я пока не понял)
1
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
11.10.2016, 12:33  [ТС] 3
Цитата Сообщение от si1n3rd Посмотреть сообщение
Ошибку не выводит, потому что здесь уместно предупреждение
А кто так решил? По мне, ошибка должна быть, ибо функции явно передается не тот тип что она ожидает иначе смысл типизации?

Цитата Сообщение от si1n3rd Посмотреть сообщение
Откуда берется 71 я пока не понял)
Аналогично
0
48 / 46 / 18
Регистрация: 27.04.2016
Сообщений: 169
11.10.2016, 13:03 4
Цитата Сообщение от sys_beginner Посмотреть сообщение
А кто так решил?
Так решили разработчики компилятора. И, если я не ошибаюсь, то ответственность за такие случаи лежит на самом программисте. В этом и вся суть свободы Си, иногда за многие вещи отвечает лично программист. В Си кстати нестрогая типизация, иными словами слабая: "Языки со слабой типизацией выполняют множество неявных преобразований автоматически, даже если может произойти потеря точности или преобразование неоднозначно."
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
11.10.2016, 13:10 5
Си в отсутствии прототипа функции принимает ее как есть. Если не приложить специальных усилий (выставить флаги предупреждений). Да и с ними будет только Warring.
И работает просто. Помещает в стек то, что ему дают. А уж сама функция работает с тем, что дали (с тем, что находится в стеке). Понятно, что получается абракадабра. Но это уже твоя беда.
0
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
11.10.2016, 13:13  [ТС] 6
si1n3rd,
Насчет числовых преобразований читал, но когда char путается со строковым литералом или double, то это уже чушь получается. Что типизация есть что её нет почти одно и тоже. Но если использовать прототип функции то код не компилируется.

Добавлено через 2 минуты
Цитата Сообщение от Байт Посмотреть сообщение
Си в отсутствии прототипа функции принимает ее как есть.
Насколько знаю, генерируется прототип на основе первого вызова и подразумевается, что функция возвращает int а её аргументы соответствуют аргументам первого вызова. Если это правда, то при втором вызове программа так же должна была отвалиться ибо при первом вызове прототип был создан автоматически и второй вызов ему не соответствует. Информация отсюда https://www.opennet.ru/docs/RU... i-c-7.html пункт 7.3 Прототипы функций (Объявления)
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
11.10.2016, 13:22 7
Мой старенький BC 2.0 ругнулся на void. А все остальное с удовольствием схавал.
Но вообще, Си в отличие от Паскаля был создан программистами для программистов. Таких же как они. И отслеживать все возможные идиотизмы не входило в задачу создателей. Они как-то доверяли тем, кто будет ихним созданием пользоваться.
2
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
11.10.2016, 13:27  [ТС] 8
Байт,
Причем такое поведение происходит только если функция вызывается до её определения либо если отсутствует прототип.
Цитата Сообщение от Байт Посмотреть сообщение
И отслеживать все возможные идиотизмы не входило в задачу создателей
Это конечно хорошо, но немного не соглашусь. Если компилятор требует указание типа, то он обязан его точно проверять, думаю... Исключение могут составлять некоторые оговоренные правила, но что бы не было бардака о котором эта тема

Добавлено через 1 минуту
Значит, как с этим бороться? В каждом файле перед использованием функций описывать прототип?
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
11.10.2016, 13:36 9
Лучший ответ Сообщение было отмечено Undisputed как решение

Решение

Цитата Сообщение от sys_beginner Посмотреть сообщение
но немного не соглашусь.
Все претензии к авторам языка. С Деннисом Ричи вам, я думаю, в ближайшие годы поговорить не удастся. А Керниган еще жив...
Цитата Сообщение от sys_beginner Посмотреть сообщение
В каждом файле перед использованием функций описывать прототип?
Да, рекомендуется. Но не в файле, конечно, а в хедере. Для того-то эти хедеры и придуманы. Или, если функция используется только в этом файле, помещать ее реализацию до использования. В этом случае хорошо бы еще дать ей спецификацию static.
1
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
11.10.2016, 13:56  [ТС] 10
Байт,
Спасибо за информацию. Значит есть файл some.c и все прототипы его функций писать в some.h?

А не проще поместить все файлы с функциями в файле с main в первую очередь и не париться с прототипами?
А в других файлах просто вызывать эти функции и таким образом объявить все функции до их первого вызова
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
11.10.2016, 14:05 11
Цитата Сообщение от sys_beginner Посмотреть сообщение
и все прототипы его функций писать в some.h?
Да где хошь. Я вот обычно все функции в одном-двух хедерах объявляю. Дело вкуса.
Цитата Сообщение от sys_beginner Посмотреть сообщение
А в других файлах просто вызывать эти функции и таким образом объявить все функции до их первого вызова
Каждый файл компилируется независимо от остальных. Подумай.
0
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
11.10.2016, 14:12  [ТС] 12
Цитата Сообщение от Байт Посмотреть сообщение
Каждый файл компилируется независимо от остальных. Подумай.
То есть не будет работать? Даже если использовать extern?
0
48 / 46 / 18
Регистрация: 27.04.2016
Сообщений: 169
11.10.2016, 14:31 13
Цитата Сообщение от Байт Посмотреть сообщение
Но вообще, Си в отличие от Паскаля был создан программистами для программистов. Таких же как они. И отслеживать все возможные идиотизмы не входило в задачу создателей.
Я думаю этот ответ идеальный.
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
11.10.2016, 15:00 14
Цитата Сообщение от sys_beginner Посмотреть сообщение
То есть не будет работать? Даже если использовать extern?
Еще подумай
Цитата Сообщение от Байт Посмотреть сообщение
Каждый файл компилируется независимо от остальных.
0
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
11.10.2016, 15:03  [ТС] 15
Байт,
Ещё один вариант, если понадобится использовать отдельный скомпилированный файл в качестве библиотеки то ничего не выйдет. Но в контексте общей программы все будет работать (сейчас негде протестировать)
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
11.10.2016, 17:27 16
Цитата Сообщение от Байт Посмотреть сообщение
Еще подумай
Да, не получается пока.
Смотри. Вот есть файл second.cpp. Компилятор, занимаясь этим файлом, не видит более ничего, кроме этого файла. Да, он видит всякие свои таблицы, свои файлы, но из того что ты накатал, он видит только этот second.cpp. Спрашивается, а как же хедеры? А они просто вставляются в то место, где оказалась директива #include и больше ничего. Они просто оказались частью твоего second.cpp, и вот их компилятор видит. А то, что ты накатал в main.cpp он не видит и не знает. И никакие extern там не спасут. Никакой мистики нет. Есть только файлы. И каждый компилируется сам по себе. И компилятор видит в данный момент времени только то, что в этом файле написано
Потом, правда, работает линковщик, он собирает все получившиеся ОБЪЕКТНЫЕ файлы в одну кучу, т.е. в исполняемый файл, экзэшник, но это совсем другой разговор
2
Вездепух
Эксперт CЭксперт С++
11694 / 6373 / 1723
Регистрация: 18.10.2014
Сообщений: 16,066
11.10.2016, 17:44 17
Цитата Сообщение от sys_beginner Посмотреть сообщение
Почему не выводятся ошибки?
Во-первых, ваш код формально корректен (с точки зрения компиляции, а не поведения) только в "классическом" С образца 89/90 года. С точки зрения современного С (С99, С11) код не корректен.

Во-вторых, в С нет понятия "ошибки", а есть понятие "нарушения ограничений" (constraint violation), в ответ на которое компилятор должен ввдать диагностическое сообщение. В вашем случае диагностических сообщений был выдан целый ворох, а вы их просто проигнорировали.
1
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
11.10.2016, 20:07  [ТС] 18
Цитата Сообщение от Байт Посмотреть сообщение
Смотри. Вот есть файл second.cpp. Компилятор, занимаясь этим файлом, не видит более ничего, кроме этого файла. Да, он видит всякие свои таблицы, свои файлы, но из того что ты накатал, он видит только этот second.cpp. Спрашивается, а как же хедеры? А они просто вставляются в то место, где оказалась директива #include и больше ничего. Они просто оказались частью твоего second.cpp, и вот их компилятор видит.
Разве компилятор включает файлы? Насколько мне известно, этим занимается препроцессор, а его результат уже обрабатывает компилятор. Файлы разве не рекурсивно подключаются? В first.c подключен second.c, а в second.c подключается third.c. Когда будет подключаться first.c, будет подключен и second.c, так? Если при обработке second.c так же подключится и third.c, то есть если подключения происходит рекурсивно, не могу понять, в чем проблема способа который я описал? Разве нельзя построить цепочку подключения файлов соответствующим образом?

Добавлено через 6 минут
Это конечно же в том случае, если начать компиляцию с main.c
0
Диссидент
Эксперт C
27706 / 17322 / 3812
Регистрация: 24.12.2010
Сообщений: 38,979
11.10.2016, 20:13 19
Цитата Сообщение от sys_beginner Посмотреть сообщение
этим занимается препроцессор
Верно. Просто я не стал заострять на этом внимание.
Цитата Сообщение от sys_beginner Посмотреть сообщение
Файлы разве не рекурсивно подключаются?
Тоже верно.
Цитата Сообщение от sys_beginner Посмотреть сообщение
В first.c подключен second.c, а в second.c подключается third.c.
Ну, если ты так строишь свои программы, то Бог в помощь. Однако, почему-то так никто не делает. И наверное, есть причины.
Обычно с-файлы перечисляются в проекте Каждый с- срр-файл транслируется отдельно и потом объектные модули собираются линковщиком. Но ты в праве делать и так. Правда, когда твой проект станет чуток побольше, я тебе не позавидую.
1
875 / 461 / 91
Регистрация: 10.06.2014
Сообщений: 2,669
11.10.2016, 20:33  [ТС] 20
Байт,
Мне главное было понять принцип, спасибо за объяснение
0
11.10.2016, 20:33
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
11.10.2016, 20:33
Помогаю со студенческими работами здесь

Код не компилируется
В чем ошибка? Не хочет запускаться. Среда Pelles C. #include &lt;stdio.h&gt; #include &lt;locale.h&gt;...

Не компилируется код
#include &lt;iostream&gt; #include &lt;iomanip&gt; #include &lt;stdlib.h&gt; #include &lt;math.h&gt; using namespace...

Не компилируется код примера из книги
/*Списал код с книги. Visio 2012 не может его даже скомпилировать, а GCC не выводит...

Не компилируется код первой программы на C
Почему не компилируется код в IDE CodeBlocks? /*Выводит сообщение на экране*/ #include...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru