Почему мы не получаем ошибку времени компиляции, даже если мы не включаем stdio.h в программу C?

Виджеты Jupyter - хороший способ отображения анимации. В приведенном ниже коде показан анимированный gif .....

from ipywidgets import Image
from IPython import display
animatedGif = "animatedGifs/01-progress.gif" #path relative to your notebook
file = open(animatedGif , "rb")
image = file.read()
progress= Image(
    value=image,
    format='gif',
    width=100,
    height=100)
display.display(progress)

Вы можете закрыть эту анимацию, используя:

progress.close()

N.B. Я нашел несколько приятных анимированных gifs из http://www.downgraf.com/inspiration/25-beautiful-loading-bar-design-examples-gif-animated/ .

6
задан Jason Plank 1 November 2011 в 12:06
поделиться

7 ответов

Испытывая недостаток в более определенном прототипе, компилятор предположит, что функция возвращает интервал и берет любое количество аргументов, которые Вы обеспечиваете.

В зависимости от архитектуры ЦП аргументы могут быть переданы в регистрах (например, a0 через a3 на MIPS) или путем продвижения их на стек как в исходном x86 соглашении о вызовах. В любом случае передача дополнительных аргументов безопасна. Вызванная функция не будет использовать регистры, переданные в, ни ссылаться на дополнительные аргументы на стеке, но ничего плохо не происходит.

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

10
ответ дан 8 December 2019 в 05:24
поделиться

C предположит интервал для неизвестных типов. Так, это, вероятно, думает, что сон имеет этот прототип:

int sleep(int);

Что касается предоставления нескольких параметров и соединения... Я не уверен. Это действительно удивляет меня. Если это действительно работало, то, что произошло во времени выполнения?

2
ответ дан 8 December 2019 в 05:24
поделиться

В классике C Вам не нужен прототип для вызывания функции. Компилятор выведет, что функция возвращает интервал и берет неизвестное количество параметров. Это может работать над некоторой архитектурой, но это перестанет работать, если функция возвратит что-то другое, чем интервал, как структура, или если существуют какие-либо преобразования параметра.

В Вашем примере замечен сон, и компилятор принимает прототип как

int sleep();

Обратите внимание, что список аргументов пуст. В C это не то же как пусто. Это на самом деле означает "неизвестный". Если бы Вы писали K&R C код, то у Вас могли бы быть неизвестные параметры через код как

int sleep(t)
int t;
{
   /* do something with t */
}

Это все опасно, особенно на некоторых встроенных микросхемах, где способ, которым параметры передаются для несмоделированной функции, не соглашается от одного с прототипом.

Примечание: прототипы не необходимы для соединения. Обычно, компоновщик автоматически связывается с библиотекой времени выполнения C как glibc на Linux. Ассоциация между Вашим использованием сна и кодом, который реализует его, происходит во время ссылки еще долго после того, как исходный код был обработан.

Я предложил бы, чтобы Вы использовали функцию своего компилятора, чтобы потребовать, чтобы прототипы избежали проблем как это. С GCC это - Wstrict-опытный параметр командной строки. В инструментах CodeWarrior это был флаг "Require Prototypes" в панели Compiler C/C++.

5
ответ дан 8 December 2019 в 05:24
поделиться

Другие ответы касаются вероятной механики (все предположения как компилятор, не указанный).

Проблема, которую Вы имеете, - то, что Ваш компилятор и компоновщик не были установлены включить каждую возможную ошибку и предупреждение. Для любого нового проекта нет (фактически) никакого оправдания за то, что не сделали так. для проектов прежней версии больше оправдания - но должен стремиться включить как можно больше

2
ответ дан 8 December 2019 в 05:24
поделиться

Зависит от компилятора, но с gcc (например, так как это - то, которое Вы упомянули), часть стандарта (и C и POSIX) функции имеют встроенный "компилятор intrinsics". Это означает, что библиотека компилятора, поставленная с Вашим компилятором (libgcc в этом случае), содержит реализацию функции. Компилятор позволит неявное объявление (т.е. использование функции без заголовка), и компоновщик найдет реализацию в библиотеке компилятора, потому что Вы, вероятно, используете компилятор в качестве фронтенда компоновщика.

Попытайтесь компилировать свои объекты с '-c' флаг (скомпилируйте только, никакая ссылка), и затем свяжите их непосредственно использование компоновщика. Вы найдете, что получаете ошибки компоновщика, которые Вы ожидаете.

С другой стороны, gcc поддерживает опции отключить использование intrinsics: -fno-builtin или для детализированного управления, -fno-builtin-function. Существуют дальнейшие опции, которые могут быть полезными, если Вы делаете что-то как создание доморощенного ядра или некоторого другого вида приложения на металле.

1
ответ дан 8 December 2019 в 05:24
поделиться

Это относится к чему-то позвонившему 'K & R C' и 'ANSI C'. В старой доброй K & R C, если что-то не объявляется, это, как предполагается, интервал. Таким образом, любая вещь, которая похожа на вызов функции, но не объявленная как функция, автоматически возьмет возвращаемое значение 'международных' и типов аргумента в зависимости от фактического вызова.

Однако люди позже выяснили, что это может иногда быть очень плохо. Таким образом, несколько компиляторов добавили предупреждение. C++ совершил эту ошибку. Я думаю, что gcc имеет некоторый флаг (-ansic или - педантичный?), которые делают это условие ошибкой.

Так, Короче говоря это - исторический багаж.

2
ответ дан 8 December 2019 в 05:24
поделиться

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

1
ответ дан 8 December 2019 в 05:24
поделиться
Другие вопросы по тегам:

Похожие вопросы: