Форум программистов, компьютерный форум CyberForum.ru

Ссылки и указатели - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Построение UML http://www.cyberforum.ru/cpp-beginners/thread250365.html
Можно ли создать диаграмму зависимостей UML из существующего проекта VS 2005?
C++ написать программу если можно с объяснением!!!!!!!! http://www.cyberforum.ru/cpp-beginners/thread250357.html
C++ класс эллипс
ПОМОГИТЕ ПОЖАЛУЙСТА, начала изучать с++ столкнулась с такой вот задачей...... Определить класс эллипс, продемонстрировать использование класса. Члены класса: переменные, необходимые для того, чтобы иметь возможность пользоваться стандартными функциями рисования. Обязательны функции-члены класса: нарисовать, стереть, передвинуть эллипс, изменить радиусы эллипса. может у кого есть примеры для...
C++ Сложение, вычитание, умножение
Доброго времени суток! Помогите с задачей: Написать функцию, которая складывает, вычитает или умножает два целых числа и возвращает результат (операнды и знак операции +, – или * — параметры функции). Заранее Спасибо! PS есть наработки, но чёт не так, выдаёт ошибки: num1.cpp #include<iostream>
C++ Преобразование массива с использованием функции http://www.cyberforum.ru/cpp-beginners/thread250350.html
На языке С написать с помощью функции программу. Задание: Дана матрица А и вектор B. Из сумм элементов строк матрицы сформировать вектор C. Если минимальный элемент вектора C кратен минимальному элементу вектора B, то из положительных элементов матрицы А сформировать вектор D и упорядочить его по возрастанию. Иначе матрицу А упорядочить по возрастанию. Заранее благодарен...
C++ указатель(?) на массив ситуация: мне нужно, чтобы в main был определён двумерный массив, а класс мог бы его использовать: class map { unsigned short int *field; bool isVisiable; public: map(unsigned short int ???); void show (); void hide (); подробнее

Показать сообщение отдельно
Evg
Эксперт CАвтор FAQ
17470 / 5708 / 363
Регистрация: 30.03.2009
Сообщений: 15,670
Записей в блоге: 26
15.07.2011, 19:14     Ссылки и указатели
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
Я когда-то исследовал функции с переменным числом параметров и тоже вовсю использовал преобразование указателей. Было интересно передать в функцию с переменным числом параметров указатели на функции с разным числом параметров и там все их вызвать...
С точки зрения языка сие допустимо, но по сути дела это UB, потому как в точке вызова и в точке самой функции должны быть одинаковые прототипы. Возьмём пример из двух файлов:

C
1
2
3
4
5
6
7
8
extern void func (float f1, float f2);
 
int
main (void)
{
  func (1.25, 2.75);
  return 0;
}
C
1
2
3
4
5
6
7
#include <stdio.h>
 
void
func (int f1, int f2)
{
  printf ("f1=%x, f2=%x\n", f1, f2);
}
Мы видим, что в точке вызова прототип описан как с двумя float'ами, а в точке реализации - с двумя int'ами. Два файла компилируются раздельно, а потому для компилятора они оба корректные. Линкер работает только с именами: он видит, что в одном модуле есть определение символа "func", а в другом - использование символа с таким же именем, а потому он свяжет эти две точки и всё. Такой код будет работать. При исполнении он выдаст:

Код
f1=3fa00000, f2=40300000
В точке вызова компилятор передаст параметры, которые есть наборы битов для представления констант 1.25 и 2.75 как float. А а в самой функции из этого же места прочтутся эти же самые наборы битов, но будут трактоваться как int'ы (от чего и напечатаны такие значения). Казалось бы, что поведение программы всё равно оказывается детерминированным. А на самом деле это не так. В случае i386 при передаче целых и плавающих значений используются одни и те же программные соглашения. В нашем случае размер int'а совпадает с размером float'а, а потому место, через которое передаются параметры (видимо это стек) совпадёт с местом, откуда они читаются. На архитектуре sparc v9 программные соглашения устроены таким образом, что для целых и плавающих значений используются разные правила передачи параметров. В этом случае параметры типа float передадутся на плавающих регистрах, а параметры типа int будут прочитаны с целочисленных регистров (и окажутся неинициализированными).

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

Ну и такие же риски имеются, если с var_arg'ами работать так, как в начальных примерах твоей статьи - непосредственно через указатели

Добавлено через 1 минуту
Да, забыл сказать. Это пример работает только в Си, потому как с точки зрения Си++ функции с одним именем, но разными типами параметров - это разные функции
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru