Такая функция portable невозможна.
Ваша попытка, вероятно, настолько близка, насколько это возможно, но вычитание указателя имеет неопределенное поведение. В более общем смысле p1 - p0
, где p0
и p1
являются указателями на разные объекты, имеет неопределенное поведение.
За исключением того, что ваш код вычитает до int
значений, которые являются результатом конверсий из адресов. Скорее всего, будет работать прямое вычитание указателей, и указатели должны быть типа char*
или unsigned char*
. Есть много реализаций, в которых int
слишком мал для хранения преобразованного указателя, а в некоторых указатели имеют более сложное представление, чем вы предполагаете, и преобразование их даже в достаточно большой целочисленный тип не обязательно даст вам осмысленный результат.
Существуют реальные реализации C, которые не используют «стек» в смысле непрерывной области памяти, в которую помещаются и извлекаются «кадры стека». (Должен существовать «стек» в смысле структуры данных «первым поступил — последним обслужен», но способ реализации этого «стека» совершенно не определен.) Некоторые реализации мэйнфреймов IBM, например, выделяют память для функции. call через что-то вроде кучи, чтобы не было определенной связи между адресами локальных переменных для двух таких вызовов.
Возможно, вы сможете написать функцию на чистом C (без языка ассемблера), которая даст вам размер кадра стека для конкретной реализации. Но поскольку в самом языке C нет понятия «фрейм стека» (в стандарте даже не используется слово «стек»), это невозможно сделать переносимым.
person
Keith Thompson
schedule
06.02.2015