Для других людей, занимающихся этим направлением. Существует неплохая запись в блоге и ссылка на библиотеку , которая предлагает Flask-SQLAlchemy как преимущества, без прямого связывания SQLAlchemy с Flask.
Однако слово предупреждения; Я пытался использовать Alchy, но все еще не мог понять, как интегрировать его в Flask и не-web-приложение, поэтому я пошел с принятым ответом давидизма на этот вопрос. Ваш пробег может отличаться.
Вы, вероятно, знаете, что прототип функции printf выглядит примерно так
int printf(const char *format, ...);
Более полной версией этого может быть
int __cdecl printf(const char *format, ...);
__cdecl
определяет "соглашение о вызовах", которое, наряду с другими вещи, описывает, как обрабатываются аргументы. В данном случае это означает, что аргументы помещаются в стек и стек очищается функцией, выполняющей вызов.
Одной из альтернатив _cdecl
является __stdcall
, есть и другие. С __stdcall
соглашение заключается в том, что аргументы помещаются в стек и очищаются вызываемой функцией. Однако, насколько мне известно, функция __stdcall
не может принимать переменное количество аргументов. Это имеет смысл, поскольку он не будет знать, сколько стека нужно очистить.
Если кратко, то в случае с функциями __cdecl
безопасно передавать столько аргументов, сколько вы хотите, поскольку очистка выполняется в коде, выполняющем вызов. Если вы каким-то образом передадите слишком много аргументов функции __stdcall
, это приведет к повреждению стека. Одним из примеров того, где это может произойти, является неправильный прототип.
Дополнительную информацию о соглашениях о вызовах можно найти в Википедии здесь.
Все аргументы будут помещены в стек и удалены, если фрейм стека удален. это поведение не зависит от конкретного процессора. (Помню только мейнфрейм без стека, разработанный в 70-х) Так что да, второй пример не подведёт.
printf
предназначен для приема любого количества аргументов. Затем printf считывает спецификатор формата (первый аргумент) и при необходимости извлекает аргументы из списка аргументов. Вот почему слишком мало аргументов дает сбой: код просто начинает использовать несуществующие аргументы, обращаться к несуществующей памяти или что-то еще плохое. Но при слишком большом количестве аргументов лишние аргументы будут просто проигнорированы. Спецификатор формата будет использовать меньше аргументов, чем было передано.
Онлайн-проект стандарта C (n1256) , раздел 7.19.6.1, параграф 2:
Функция fprintf записывает вывод в поток, на который указывает stream, под управлением строки указывается форматом, который указывает, как последующие аргументы преобразованы для вывода. Если для формата недостаточно аргументов, поведение неопределенный. Если формат исчерпан, а аргументы остались, лишние аргументы оцениваются (как всегда), но в противном случае игнорируются. Функция fprintf возвращает значение, когда встречается конец строки формата.
Поведение всех остальных функций *printf()
такое же, как и для избыточных аргументов, за исключением vprintf()
(очевидно).
Комментарий: и gcc, и clang выдают предупреждения:
$ clang main.c
main.c:4:29: warning: more '%' conversions than data arguments [-Wformat]
printf("Gonna %s and %s, %s!", "crash", "burn");
~^
main.c:5:47: warning: data argument not used by format string
[-Wformat-extra-args]
printf("Gonna %s and %s!", "crash", "burn", "dude");
~~~~~~~~~~~~~~~~~~ ^
2 warnings generated.