Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
Gepar
1178 / 534 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
#1

GCC и функции с переменным числом аргументов - C++

29.09.2013, 01:43. Просмотров 610. Ответов 7
Метки нет (Все метки)

Писал мини приложение в студии для работы с векторами, один из методов просто получает сколько угодно аргументов и заполняет координаты вектора по разным измерениям этими данными (и так либо пока данные не закончаться либо пока кол-во измерений указанное при создании вектора не закончиться). Привожу код:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#define newGVector ((GVector*) malloc(sizeof(GVector)))
 
struct GVector{
    int dimSize;
    double* data;
};
 
GVector* createVector(int dimSize){
    GVector* vec = newGVector;
    vec->data = (double*) malloc((vec->dimSize = dimSize) * sizeof(double) );
    return vec;
}
 
GVector* initVector(GVector* vec, double item, ...){
    int i, dimSize = vec->dimSize;
    double* items = &item;
    for (i = 0; i < dimSize && items; i++)
        vec->data[i] = *items, items++;
    return vec;
}
 
void printVec(GVector* vec){
    int i;
    printf("[");
    for(i=0; i<vec->dimSize-1; i++)
        printf("%-6.1f",vec->data[i]);
    printf("%.1f]\n",vec->data[i]);
}
При компиляции компилятором microsoft вот этого кода всё хорошо:
C
1
2
3
4
    printf("First vector:\n");
    GVector* vec1 = createVector(3);
    initVector(vec1, 1.0, 2.0, 3.0);
    printVec(vec1);//выведет [1.0 2.0 3.0]
Но если компилирую через gcc то мой метод вместо значений подтягивает мусор:
C
1
2
3
4
    printf("First vector:\n");
    GVector* vec1 = createVector(3);
    initVector(vec1, 1.0, 2.0, 3.0);
    printVec(vec1);//выведет [1.0 1.$ 0.0]
Тоесть первое значение оно подхватывает, вместо следующего всегда 1.$, а дальше идут нули. Я так понимаю что gcc решили выпендриться и по своему сделали передачу аргументов функциям, я так догадываюсь что второе это указатель на область памяти где именно те аргументы или ещё что-то хитрое, подскажите пожалуйста можно ли заставить gcc поступать с аргументами функций так же как и остальные компиляторы? Просто вариант с va_list мне не нравиться - там ведь получаеться нельзя двигаться по списку аргументов не зная заранее сколько их, а я хотел бы чтобы не надо было передавать никаких int count, а просто только значения и всё, ну как у меня в текущем варианте, с va_list выходит это не получиться ... или получиться ?
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
29.09.2013, 01:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос GCC и функции с переменным числом аргументов (C++):

Функции с переменным числом аргументов - C++
на пример sum(2,56,515,-23.65,548)?

Шаблон с переменным числом аргументов, и возвращаемое значение функции - C++
Здравствуйте! Использую С++11. Хочу возвращать элементы кортежа пытаюсь так, auto Deserialize(unsigned long long i) -&gt;...

Шаблоны с переменным числом аргументов - C++
Написал шаблон функции с переменным числом аргументов которая считает сумму своих аргументов. Практики по этому вопросу не имею, поэтому...

Шаблонная функция с переменным числом аргументов - C++
Сабж. Каким образом можно запретить использование шаблонной функции, если тип одного из аргументов не соответствует требуемому? Есть...

Функция с переменным числом аргументов (через шаблоны) - C++
Доброго времени суток! Встал вопрос с реализацией такой функции. template&lt;typename... Args&gt; returntype functionname(const Args&amp;......

Инициализация std::tuple переменным числом аргументов - C++
Добрый вечер. Мне нужно инициализировать объект std::tuple, который является членом некоторого другого шаблонного класса с переменным...

7
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
29.09.2013, 02:42 #2
В release правильно выводит.
1
OhMyGodSoLong
~ Эврика! ~
1244 / 993 / 42
Регистрация: 24.07.2012
Сообщений: 2,002
29.09.2013, 03:00 #3
Лучший ответ Сообщение было отмечено автором темы, экспертом или модератором как ответ
Цитата Сообщение от Gepar Посмотреть сообщение
Просто вариант с va_list мне не нравиться - там ведь получаеться нельзя двигаться по списку аргументов не зная заранее сколько их, а я хотел бы чтобы не надо было передавать никаких int count, а просто только значения и всё, ну как у меня в текущем варианте, с va_list выходит это не получиться ... или получиться ?
Undefined behavior типа больше нравится.

Если initVector() обязана быть безопасной (то есть нельзя взять с пользователя честное пионерское, что он всегда будет передавать столько аргументов, сколько в vec->dimSize), то придётся извращаться. Идиома работы с va_list: в списке аргументов всегда есть что-то, позволяющее определить, сколько и чего там функции передали. (Ну, или честное слово, да.) Обычно это явное количество одинаковых аргументов (этот самый count), строка формата а-ля print(), или специальное значение "конец списка аргументов" (для double можно NaN взять). Первый и последний варианты в принципе можно макросами спрятать, если дописывание этих штук вызывает невыносимые физические страдания.

Не по теме:

И вообще, accept the challenge: генератор векторов на макросах!

0
Gepar
1178 / 534 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
29.09.2013, 13:57  [ТС] #4
Цитата Сообщение от alsav22 Посмотреть сообщение
В release правильно выводит.
Неа, в release дочитывает нулями почему-то

Цитата Сообщение от OhMyGodSoLong Посмотреть сообщение
Идиома работы с va_list: в списке аргументов всегда есть что-то, позволяющее определить, сколько и чего там функции передали. (Ну, или честное слово, да.)
Видимо придёться рассчитывать на честное слово, хоть мне и не нравиться это решение.
0
alsav22
5428 / 4823 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
29.09.2013, 18:16 #5
Цитата Сообщение от Gepar Посмотреть сообщение
Неа, в release дочитывает нулями почему-то
Я там небольшое изменение в коде сделал. Подумал, что это никак не может влиять на правильный вывод, поэтому и написал, что в release правильно выводит. Оказалось, что влияет. Если сделать дополнительный вывод в initVector, то, почему-то, правильно начинает выводить в release:
C++
1
2
3
4
5
6
7
8
9
10
11
12
GVector* initVector(GVector* vec, double item, ...)
{
    int i, dimSize = vec ->dimSize;
    double* items = &item;
    for (i = 0; i < dimSize && items; i++)
    {
        vec->data[i] = *items;
        cout << vec->data[i] << endl;
        ++items;
    }
    return vec;
}
0
castaway
Эксперт С++
4916 / 3024 / 370
Регистрация: 10.11.2010
Сообщений: 11,081
Записей в блоге: 10
Завершенные тесты: 1
29.09.2013, 19:32 #6
А почему вы решили что items в конце списка станет == 0 ?
dimSize в цикле вообще нигде не изменяется. По какому условию цикл должен прекратиться?
0
kamre
126 / 130 / 4
Регистрация: 25.12.2011
Сообщений: 443
30.09.2013, 08:33 #7
Цитата Сообщение от Gepar Посмотреть сообщение
один из методов просто получает сколько угодно аргументов и заполняет координаты вектора по разным измерениям этими данными (и так либо пока данные не закончаться либо пока кол-во измерений указанное при создании вектора не закончиться)
Может быть автор форумом ошибся и ему нужно в форум по C. А то непонятно зачем городить такой GVector самому вместо использования std::vector<double>, для которого и так все работает:
C++
1
2
3
4
5
6
typedef std::vector<double> GVector;
 
void test() {
    GVector v = { 1.0, 2.0, 3.0 };
    v = { 3.0, 2.0, 1.0 };
}
И функцию, если такая действительно нужна, можно реализовать примерно так:
C++
1
2
3
4
5
6
7
8
template <typename... Ts>
void initVector(GVector& v, const Ts&... ts) {
    double ds [] = { ts... };
    size_t n = std::min(sizeof...(ts), v.size());
    for (size_t i = 0; i < n; ++i) {
        v[i] = ds[i];
    }
}
1
Gepar
1178 / 534 / 20
Регистрация: 01.07.2009
Сообщений: 3,517
30.09.2013, 23:36  [ТС] #8
Цитата Сообщение от kamre Посмотреть сообщение
Может быть автор форумом ошибся и ему нужно в форум по C.
В этом плане таки да, забыл что с определённого времени тут отдельно си и с++, ну да уже поздно.

Цитата Сообщение от kamre Посмотреть сообщение
А то непонятно зачем городить такой GVector самому вместо использования std::vector<double>
Ну как зачем, студенческие задания естественно, так бы я сам велосипеды для реального использования не писал бы.
0
30.09.2013, 23:36
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
30.09.2013, 23:36
Привет! Вот еще темы с ответами:

Как изменить значение переменной, переданной в списке с переменным числом аргументов - C++
Помогите!!! Начал изучать С++ Возникла такая проблема. Когда мне нужно получить доступ к переменному числу аргументов я делаю что-то...

Шаблон функции с переменным количеством аргументов - C++
Добрый вечер, мне необходимо при помощи шаблона функции реализовать поиск минимального числа(тип данных не известен, количество чисел...

Функции с переменным числом параметров - C++
Написать функцию prost с переменным числом параметров, которая находит все простые числа из нескольких интервалов. Интервалы задаются...

Функции с переменным числом параметров - C++
Написать функцию max с переменным числом параметров, которая находит минимальное из чисел типа int или из чисел типа double, тип параметров...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.