LINUX.ORG.RU

История изменений

Исправление 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(). И сделать функцию, которая принимает заодно и кол-во аргументов.