История изменений
Исправление
kirk_johnson,
(текущая версия)
:
функции va* - получение доступа к значениям из переданных списком аргументов. Для предотвращения ошибок подсчёта текущего количества уже считанного, в C принято неопределённое заранее количество аргументов передавать только через стек.
Увы, нет. На x86_64 допустимо передавать через регистры.
Вот тут чувак об этом пишет: https://blog.nelhage.com/2010/10/amd64-and-va_arg/
Макросы va* разворачиваются иногда даже не в ассемблерные, а C-шные простейшие манипуляции с указателями. Откуда тут могут быть неопределенное поведение?
Потому что стандарт так говорит. Как именно закодили va_arg() — не определено стандартом. Он может хоть через UDP у соседнего датацентра запрашивать аргументы.
Проблему вы выявили интересную: именно всё выше сказанное не относится именно к сисколам:
Да что вы к сисколам-то привязались? Это просто функция, в которой баг. Там есть другие такие же функции. Дело не в том, что тут сисколы, а в том, что va_arg() неправильно используют. Почему только mironov_ivan это с первого раза понял?
там принято максимально юзать регистры, и только когда уж совсем их не остаётся, то передавать значение в сискол через стек.
Господи Иисусе, мне кажется, что вы с Iron_Bug какой-то другой тред читаете. Что там ядро с сисколами делает — тут абсолютно нерелевантно, UB в неверном использовании va_arg().
Но проблема старая: как делать C-шные декларации, без расширений языка? В конкретных компиляторах выкручиваются своими собственными расширениями, декларируюя очень по особенному такие функции, что они вроде и с переменным количеством аргументов, но с принятым в этой ОС количеством передаваемых аргументов прежде в регистрах.
Очень просто — убрать к черту функцию из стандарта, как это сделали с gets(). И сделать функцию, которая принимает заодно и кол-во аргументов. Ну или переписать её на asm, с ним проблемы не будет, потому что он просто копирует регистры, а не зовет va_arg().
Исправление
kirk_johnson,
:
функции va* - получение доступа к значениям из переданных списком аргументов. Для предотвращения ошибок подсчёта текущего количества уже считанного, в C принято неопределённое заранее количество аргументов передавать только через стек.
Увы, нет. На x86_64 допустимо передавать через регистры.
Вот тут чувак об этом пишет: https://blog.nelhage.com/2010/10/amd64-and-va_arg/
Макросы va* разворачиваются иногда даже не в ассемблерные, а C-шные простейшие манипуляции с указателями. Откуда тут могут быть неопределенное поведение?
Потому что стандарт так говорит. Как именно закодили va_arg() — не определено стандартом. Он может хоть через UDP у соседнего датацентра запрашивать аргументы.
Проблему вы выявили интересную: именно всё выше сказанное не относится именно к сисколам:
Да что вы к сисколам-то привязались? Это просто функция, в которой баг. Там есть другие такие же функции. Дело не в том, что тут сисколы, а в том, что va_arg() неправильно используют. Почему только mironov_ivan это с первого раза понял?
там принято максимально юзать регистры, и только когда уж совсем их не остаётся, то передавать значение в сискол через стек.
Господи Иисусе, мне кажется, что вы с Iron_Bug какой-то другой тред читаете. Что там ядро с сисколами делает — тут абсолютно нерелевантно, UB в неверном использовании va_arg().
Но проблема старая: как делать C-шные декларации, без расширений языка? В конкретных компиляторах выкручиваются своими собственными расширениями, декларируюя очень по особенному такие функции, что они вроде и с переменным количеством аргументов, но с принятым в этой ОС количеством передаваемых аргументов прежде в регистрах.
Очень просто — убрать к черту функцию из стандарта, как это сделали с gets(). И сделать функцию, которая принимает заодно и кол-во аргументов. Ну или переписать все на asm, где проблемы не будет.
Исправление
kirk_johnson,
:
функции va* - получение доступа к значениям из переданных списком аргументов. Для предотвращения ошибок подсчёта текущего количества уже считанного, в C принято неопределённое заранее количество аргументов передавать только через стек.
Увы, нет. На x86_64 допустимо передавать через регистры.
Вот тут чувак об этом пишет: https://blog.nelhage.com/2010/10/amd64-and-va_arg/
Макросы va* разворачиваются иногда даже не в ассемблерные, а C-шные простейшие манипуляции с указателями. Откуда тут могут быть неопределенное поведение?
Потому что стандарт так говорит. Как именно закодили va_arg() — не определено стандартом. Он может хоть через UDP у соседнего датацентра запрашивать аргументы.
Проблему вы выявили интересную: именно всё выше сказанное не относится именно к сисколам:
Да что вы к сисколам-то привязались? Это просто функция, в которой баг. Там есть другие такие же функции. Дело не в том, что тут сисколы, а в том, что va_arg() неправильно используют. Почему только mironov_ivan это с первого раза понял?
там принято максимально юзать регистры, и только когда уж совсем их не остаётся, то передавать значение в сискол через стек.
Господи Иисусе, мне кажется, что вы с Iron_Bug какой-то другой тред читаете. Что там ядро с сисколами делает — тут абсолютно нерелевантно, UB в неверном использовании va_arg().
Но проблема старая: как делать C-шные декларации, без расширений языка? В конкретных компиляторах выкручиваются своими собственными расширениями, декларируюя очень по особенному такие функции, что они вроде и с переменным количеством аргументов, но с принятым в этой ОС количеством передаваемых аргументов прежде в регистрах.
Очень просто — убрать к черту функцию из стандарта, как это сделали с gets(). И сделать функцию, которая принимает заодно и кол-во аргументов.
Исходная версия
kirk_johnson,
:
функции va* - получение доступа к значениям из переданных списком аргументов. Для предотвращения ошибок подсчёта текущего количества уже считанного, в C принято неопределённое заранее количество аргументов передавать только через стек.
Увы, нет. На x86_64 допустимо передавать через регистры.
Вот тут чувак об этом пишет: https://blog.nelhage.com/2010/10/amd64-and-va_arg/
Макросы va* разворачиваются иногда даже не в ассемблерные, а C-шные простейшие манипуляции с указателями. Откуда тут могут быть неопределенное поведение?
Потому что стандарт так говорит. Как именно закодили va_arg() — не определено стандартом. Он может хоть через UDP у соседнего датацентра запрашивать аргументы.
Проблему вы выявили интересную: именно всё выше сказанное не относится именно к сисколам:
Да что вы к сисколам-то привязались? Это просто функция, в которой баг. Там есть другие такие же функции.
там принято максимально юзать регистры, и только когда уж совсем их не остаётся, то передавать значение в сискол через стек.
Господи Иисусе, мне кажется, что вы с Iron_Bug какой-то другой тред читаете. Что там ядро с сисколами делает — тут абсолютно нерелевантно, UB в неверном использовании va_arg().
Но проблема старая: как делать C-шные декларации, без расширений языка? В конкретных компиляторах выкручиваются своими собственными расширениями, декларируюя очень по особенному такие функции, что они вроде и с переменным количеством аргументов, но с принятым в этой ОС количеством передаваемых аргументов прежде в регистрах.
Очень просто — убрать к черту функцию из стандарта, как это сделали с gets(). И сделать функцию, которая принимает заодно и кол-во аргументов.