Фантомас 1 / 1 / 0 Регистрация: 12.02.2013 Сообщений: 18 |
||||
1 |
||||
13.02.2013, 13:37. Показов 7316. Ответов 4 Метки нет (Все метки)
Создаю текстовый массив. Выдает ошибку «error C2078: слишком много инициализаторов». При создании Int массива все нормально, а при создании екстового валит ошибку ( error C2078: слишком много инициализаторов ):
Что я наделал?)
__________________
0 |
Issues 433 / 368 / 149 Регистрация: 06.08.2012 Сообщений: 961 |
||||
13.02.2013, 13:40 |
2 |
|||
1 |
1 / 1 / 0 Регистрация: 12.02.2013 Сообщений: 18 |
|
13.02.2013, 13:45 [ТС] |
3 |
КАК, БЛИН? О_о
0 |
3985 / 3255 / 909 Регистрация: 25.03.2012 Сообщений: 12,102 Записей в блоге: 1 |
|
13.02.2013, 13:49 |
4 |
что не ясно?
1 |
1 / 1 / 0 Регистрация: 12.02.2013 Сообщений: 18 |
|
13.02.2013, 16:37 [ТС] |
5 |
Та ясно, просто после детального изучения рнр строгий синтаксис смотрится устарашающе….
1 |
Добрый день! Подскажите, пожалуйста, почему не получается определить массив? Объявляю массив таким образом:
char arr[]={"a", "b"};
Получаю такую ошибку:
error C2078: too many initializers
задан 1 апр 2013 в 18:50
Ошибка в том, что вы пытаетесь инициализировать элементы массива char[], которые имеют тип char, строковыми литералами «a» и «b», каждый из которых имеет тип char[]. Правильно для инициализации использовать символьные литералы:
char arr[] = {'a', 'b'};
На всякий случай, cледует заметить, что arr не будет являться валидной C-строкой, т.к. строка должна оканчиваться нулем. Поэтому если вы хотите получить строку, то следует добавить нулевой символ в конец:
char arr[] = {'a', 'b', ''};
или коротко:
char arr[] = "ab";
ответ дан 1 апр 2013 в 19:09
dzhioevdzhioev
11.6k23 серебряных знака38 бронзовых знаков
0
Доброго времени суток! Определитесь с тем, что хотите получить:
Массив символов:
char arr[] = { 'a', 'b' }; // кавычки одинарные!
Или массив строк:
char *arr[] = { "a", "b" }; // кавычки двойные!
ответ дан 1 апр 2013 в 19:03
progzdeveloperprogzdeveloper
1,3338 серебряных знаков15 бронзовых знаков
0
description | title | ms.date | f1_keywords | helpviewer_keywords | ms.assetid |
---|---|---|---|---|---|
Learn more about: Compiler Error C2078 |
Compiler Error C2078 |
11/04/2016 |
C2078 |
C2078 |
9bead850-4123-46cf-a634-5c77ba974b2b |
Compiler Error C2078
too many initializers
The number of initializers exceeds the number of objects to be initialized.
The compiler can deduce the correct assignment of initializers to objects and inner objects when inner braces are elided from the initializer list. Complete bracing also eliminates ambiguity and results in correct assignment. Partial bracing can cause C2078 because of ambiguity in the assignment of initializers to objects.
The following sample generates C2078 and shows how to fix it:
// C2078.cpp // Compile by using: cl /c /W4 C2078.cpp struct S { struct { int x, y; } z[2]; }; int main() { int d[2] = {1, 2, 3}; // C2078 int e[2] = {1, 2}; // OK char a[] = {"a", "b"}; // C2078 char *b[] = {"a", "b"}; // OK char c[] = {'a', 'b'}; // OK S s1{1, 2, 3, 4}; // OK S s2{{1, 2}, {3, 4}}; // C2078 S s3{{1, 2, 3, 4}}; // OK S s4{{{1, 2}, {3, 4}}}; // OK }
description | title | ms.date | f1_keywords | helpviewer_keywords | ms.assetid |
---|---|---|---|---|---|
Learn more about: Compiler Error C2078 |
Compiler Error C2078 |
11/04/2016 |
C2078 |
C2078 |
9bead850-4123-46cf-a634-5c77ba974b2b |
Compiler Error C2078
too many initializers
The number of initializers exceeds the number of objects to be initialized.
The compiler can deduce the correct assignment of initializers to objects and inner objects when inner braces are elided from the initializer list. Complete bracing also eliminates ambiguity and results in correct assignment. Partial bracing can cause C2078 because of ambiguity in the assignment of initializers to objects.
The following sample generates C2078 and shows how to fix it:
// C2078.cpp // Compile by using: cl /c /W4 C2078.cpp struct S { struct { int x, y; } z[2]; }; int main() { int d[2] = {1, 2, 3}; // C2078 int e[2] = {1, 2}; // OK char a[] = {"a", "b"}; // C2078 char *b[] = {"a", "b"}; // OK char c[] = {'a', 'b'}; // OK S s1{1, 2, 3, 4}; // OK S s2{{1, 2}, {3, 4}}; // C2078 S s3{{1, 2, 3, 4}}; // OK S s4{{{1, 2}, {3, 4}}}; // OK }
Почему этот код не работает? Моя IDE — это Visual Studio 2013.
#include <stdio.h>
float tempatureGuide(float F, float C);
#define FREEZING_PT 32.0f
#define SCALE_FACTOR (5.0f/9.0f)
int main(void)
{
float fahrenheit = 0.0;
float celsius = 0.0 ;
int convertTemp;
printf ("Enter 0 to calculate Celsius or 1 to calculate Fahrenheit: ");
scanf ("%d", &convertTemp);
if (convertTemp == 0)
{
// compute Celsius
printf("Enter Fahrenheit temperture: ");
scanf("%f", &fahrenheit);
celsius = ((fahrenheit - FREEZING_PT) * SCALE_FACTOR);
printf("Fahrenheit = %f and Celsius = %fn", fahrenheit, celsius);
float tempatureGuide(fahrenheit, celsius); // Error here
}
else
{
// compute fahrenheit
printf("Enter the temperature in degrees fahrenheitnn");
scanf("%f", &fahrenheit);
celsius = (SCALE_FACTOR)* (fahrenheit - FREEZING_PT);
printf("The converted temperature is %f", celsius);
float tempatureGuide(fahrenheit, celsius); // and here
}
return (0);
}
float tempatureGuide(float F, float C){
if (F < 32 || C < 0)
printf("It is freezing!");
else if (F <= 60 || C <= 16)
printf("It is cold");
else if (F >= 70 || C >= 21)
printf("It is just right");
else if (F >= 82 || C >= 28)
printf("It is warm");
else if (F > 95 || C > 35)
printf("It is hot");
else
printf("Please enter a number!");
return (0);
}
Цель состоит в том, чтобы добавить к проекту преобразования температуры, который я делал ранее, и добавить if else
Функция заявления к нему, что комментирует темп. Я получаю ошибку
Error 3 error C2078: too many initializes
на обеих линиях, где я вызываю свою функцию. Я искал ответ, но не мог найти.
0
Решение
Эта строка выглядит как попытка инициализации C ++ float
с одним слишком много аргументов (следовательно, «слишком много инициализаторов«ошибка), а не как вызов функции.
float tempatureGuide(fahrenheit, celsius);
Предположительно, вы хотите вызвать функцию и сохранить результат в переменной:
float temp = tempatureGuide(fahrenheit, celsius);
Или просто вызовите функцию и проигнорируйте возвращаемое значение:
tempatureGuide(fahrenheit, celsius);
Тем более что ваша функция всегда возвращает 0
Таким образом, можно задаться вопросом о необходимости не пустого типа возврата.
3
Другие решения
Вам нужно вызвать функцию
float tempatureGuide(float fahrenheit, float celsius) { //...}
как
float retval = tempatureGuide(fahrenheit, celsius);
или хотя бы
tempatureGuide(fahrenheit, celsius); // not need to use return value
Только.
1
Это просто простая ошибка. Пожалуйста, измените 2 строки кода, где вы вызываете tempatureGuide (по Фаренгейту, Цельсию); функционировать следующим образом.
float tempatureGuide(fahrenheit, celsius); --> float ret = tempatureGuide(fahrenheit, celsius);
Я протестировал то же самое в моем VS2013, так как вы используете то же самое с упомянутыми изменениями. Я могу скомпилировать и запустить его успешно. Смотрите вложение.
0
The extra braces are needed because std::array
is an aggregate and POD, unlike other containers in the standard library. std::array
doesn’t have a user-defined constructor. Its first data member is an array of size N
(which you pass as a template argument), and this member is directly initialized with an initializer. The extra braces are needed for the internal array which is being directly initialized.
The situation is same as:
//define this aggregate - no user-defined constructor
struct Aarray
{
A data[2]; //data is an internal array
};
How would you initialize this? If you do this:
Aarray a1 =
{
{0, 0.1},
{2, 3.4}
};
it gives a compilation error:
error: too many initializers for ‘Aarray’
This is the same error which you get in the case of a std::array
(if you use GCC).
So the correct thing to do is to use braces as follows:
Aarray a1 =
{
{ //<--this tells the compiler that initialization of `data` starts
{ //<-- initialization of `data[0]` starts
0, 0.1
}, //<-- initialization of `data[0]` ends
{2, 3.4} //initialization of data[1] starts and ends, as above
} //<--this tells the compiler that initialization of `data` ends
};
which compiles fine. Once again, the extra braces are needed because you’re initializing the internal array.
—
Now the question is why are extra braces not needed in case of double
?
It is because double
is not an aggregate, while A
is. In other words, std::array<double, 2>
is an aggregate of aggregate, while std::array<A, 2>
is an aggregate of aggregate of aggregate1.
1. I think that extra braces are still needed in the case of double also (like this), to be completely conformant to the Standard, but the code works without them. It seems I need to dig through the spec again!.
More on braces and extra braces
I dug through the spec. This section (§8.5.1/11 from C++11) is interesting and applies to this case:
In a declaration of the form
T x = { a };
braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; it is erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a subaggregate
does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member. [ Example:
float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 },
};
is a completely-braced initialization: 1, 3, and 5 initialize the first row of the array
y[0]
, namelyy[0][0]
,y[0][1]
, andy[0][2]
. Likewise the next two lines initializey[1]
andy[2]
. The initializer ends early and thereforey[3]s
elements are initialized as if explicitly initialized with an expression of the form float(), that is, are initialized with 0.0. In the following example, braces in the initializer-list are elided; however the initializer-list has the same effect as the completely-braced initializer-list of the above example,
float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};
The initializer for y begins with a left brace, but the one for
y[0]
does not, therefore three elements from the list are used. Likewise the next three are taken successively fory[1]
andy[2]
. —end example ]
Based on what I understood from the above quote, I can say that the following should be allowed:
//OKAY. Braces are completely elided for the inner-aggregate
std::array<A, 2> X =
{
0, 0.1,
2, 3.4
};
//OKAY. Completely-braced initialization
std::array<A, 2> Y =
{{
{0, 0.1},
{2, 3.4}
}};
In the first one, braces for the inner-aggregate are completely elided, while the second has fully-braced initialization. In your case (the case of double
), the initialization uses the first approach (braces are completely elided for the inner aggregate).
But this should be disallowed:
//ILL-FORMED : neither braces-elided, nor fully-braced
std::array<A, 2> Z =
{
{0, 0.1},
{2, 3.4}
};
It is neither braces-elided, nor are there enough braces to be completely-braced initialization. Therefore, it is ill-formed.
The extra braces are needed because std::array
is an aggregate and POD, unlike other containers in the standard library. std::array
doesn’t have a user-defined constructor. Its first data member is an array of size N
(which you pass as a template argument), and this member is directly initialized with an initializer. The extra braces are needed for the internal array which is being directly initialized.
The situation is same as:
//define this aggregate - no user-defined constructor
struct Aarray
{
A data[2]; //data is an internal array
};
How would you initialize this? If you do this:
Aarray a1 =
{
{0, 0.1},
{2, 3.4}
};
it gives a compilation error:
error: too many initializers for ‘Aarray’
This is the same error which you get in the case of a std::array
(if you use GCC).
So the correct thing to do is to use braces as follows:
Aarray a1 =
{
{ //<--this tells the compiler that initialization of `data` starts
{ //<-- initialization of `data[0]` starts
0, 0.1
}, //<-- initialization of `data[0]` ends
{2, 3.4} //initialization of data[1] starts and ends, as above
} //<--this tells the compiler that initialization of `data` ends
};
which compiles fine. Once again, the extra braces are needed because you’re initializing the internal array.
—
Now the question is why are extra braces not needed in case of double
?
It is because double
is not an aggregate, while A
is. In other words, std::array<double, 2>
is an aggregate of aggregate, while std::array<A, 2>
is an aggregate of aggregate of aggregate1.
1. I think that extra braces are still needed in the case of double also (like this), to be completely conformant to the Standard, but the code works without them. It seems I need to dig through the spec again!.
More on braces and extra braces
I dug through the spec. This section (§8.5.1/11 from C++11) is interesting and applies to this case:
In a declaration of the form
T x = { a };
braces can be elided in an initializer-list as follows. If the initializer-list begins with a left brace, then the succeeding comma-separated list of initializer-clauses initializes the members of a subaggregate; it is erroneous for there to be more initializer-clauses than members. If, however, the initializer-list for a subaggregate
does not begin with a left brace, then only enough initializer-clauses from the list are taken to initialize the members of the subaggregate; any remaining initializer-clauses are left to initialize the next member of the aggregate of which the current subaggregate is a member. [ Example:
float y[4][3] = {
{ 1, 3, 5 },
{ 2, 4, 6 },
{ 3, 5, 7 },
};
is a completely-braced initialization: 1, 3, and 5 initialize the first row of the array
y[0]
, namelyy[0][0]
,y[0][1]
, andy[0][2]
. Likewise the next two lines initializey[1]
andy[2]
. The initializer ends early and thereforey[3]s
elements are initialized as if explicitly initialized with an expression of the form float(), that is, are initialized with 0.0. In the following example, braces in the initializer-list are elided; however the initializer-list has the same effect as the completely-braced initializer-list of the above example,
float y[4][3] = {
1, 3, 5, 2, 4, 6, 3, 5, 7
};
The initializer for y begins with a left brace, but the one for
y[0]
does not, therefore three elements from the list are used. Likewise the next three are taken successively fory[1]
andy[2]
. —end example ]
Based on what I understood from the above quote, I can say that the following should be allowed:
//OKAY. Braces are completely elided for the inner-aggregate
std::array<A, 2> X =
{
0, 0.1,
2, 3.4
};
//OKAY. Completely-braced initialization
std::array<A, 2> Y =
{{
{0, 0.1},
{2, 3.4}
}};
In the first one, braces for the inner-aggregate are completely elided, while the second has fully-braced initialization. In your case (the case of double
), the initialization uses the first approach (braces are completely elided for the inner aggregate).
But this should be disallowed:
//ILL-FORMED : neither braces-elided, nor fully-braced
std::array<A, 2> Z =
{
{0, 0.1},
{2, 3.4}
};
It is neither braces-elided, nor are there enough braces to be completely-braced initialization. Therefore, it is ill-formed.
Форум программистов Vingrad
Модераторы: bsa |
Поиск: |
|
error C2078: слишком много инициализаторов, Выдает ошибку, помогите исправить |
Опции темы |
olegarh |
|
||||
Шустрый Профиль Репутация: нет
|
Добрый день, есть функция которая находит 1 максимальный элемент в массиве и выводит его индекс
функция вызывается из main.cpp
при компиляции выдает ошибку: error C2078: слишком много инициализаторов Это сообщение отредактировал(а) olegarh — 20.11.2010, 15:36 |
||||
|
|||||
SVN74 |
|
||
Опытный Профиль
Репутация: 1
|
Это сообщение отредактировал(а) SVN74 — 20.11.2010, 15:43 |
||
|
|||
sQu1rr |
|
||||||
Опытный Профиль
Репутация: 3
|
в var сохраниться результат функции Добавлено через 40 секунд
|
||||||
|
|||||||
SVN74 |
|
||
Опытный Профиль
Репутация: 1
|
delete [] arr; Это сообщение отредактировал(а) SVN74 — 20.11.2010, 15:48 |
||
|
|||
olegarh |
|
||||
Шустрый Профиль Репутация: нет
|
Функция рабочая)) все уже работает спасибо)))
надо заменить на
|
||||
|
|||||
sQu1rr |
|
||||||||
Опытный Профиль
Репутация: 3
|
Но кривая до ужаса
Во первых это все можно записать так
Но зачем max сохранять если он не используется…
|
||||||||
|
|||||||||
|
Правила форума «C/C++: Для новичков» | |
|
Запрещается! 1. Публиковать ссылки на вскрытые компоненты 2. Обсуждать взлом компонентов и делиться вскрытыми компонентами
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, JackYF, bsa. |
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) |
0 Пользователей: |
« Предыдущая тема | C/C++: Для новичков | Следующая тема » |
Заголовок winddk-8.1, который вы связали, arm_neon.h, довольно четко показывает typedef __n128 uint32x4_t; (такую же, как другие ширины элементов для 128-битных векторов), и что базовый тип __n128 сначала определяется как объединение с членом __int64[2].
typedef union __declspec(intrin_type) _ADVSIMD_ALIGN(8) __n128
{
unsigned __int64 n128_u64[2];
unsigned __int32 n128_u32[4];
unsigned __int16 n128_u16[8];
unsigned __int8 n128_u8[16];
__int64 n128_i64[2];
__int32 n128_i32[4];
__int16 n128_i16[8];
__int8 n128_i8[16];
float n128_f32[4];
struct
{
__n64 low64;
__n64 high64;
} DUMMYNEONSTRUCT;
} __n128;
Если вы хотите написать код только для MSVC, который зависит от внутренних компонентов заголовка, вы можете просто объединить пары 32-битных целых чисел в 64-битные целые числа. Для ARM с прямым порядком байтов это означает создание второго 32-битного элемента как 32-битного высокий объединенного 64-битного элемента.
#ifdef _MSC_VER
// MSVC only; will silently compile differently on others
static const uint32x4_t CTRS[3] = {
// The .n128_u64 field is first in the definition of uint32x4_t
{1 + (0ULL<<32), 0 + (0ULL<<32)}, // ARM is little-endian
{2 + (0ULL<<32), 0 + (0ULL<<32)},
{3 + (0ULL<<32), 0 + (0ULL<<32)},
};
Мы можем завершить это макросом CPP, чтобы сделать его переносимым между компиляторами.
Я сделал один макрос для всего uint32x4_t, а не парный макрос, который вы также могли бы использовать для 64-битных векторов. Это делает фактические объявления менее беспорядочными скобками и именами макросов, потому что мы можем включить внешний {} в этот макрос.
#ifdef _MSC_VER
// The .n128_u64 field is first. Combine pairs of 32-bit integers in little-endian order.
#define INITu32x4(w,x,y,z) { ((w) + (unsigned long long(x) << 32)), ((y) + (unsigned long long(z) << 32)) }
#else
#define INITu32x4(w,x,y,z) { (w), (x), (y), (z) }
#endif
static const uint32x4_t CTRS[3] = {
INITu32x4(1,0,0,0),
INITu32x4(2,0,0,0),
INITu32x4(3,0,0,0),
};
Компилируется правильно + эффективно на GCC и MSVC с правильными данными в разделе данных только для чтения (.rodata или .rdata) без инициализации среды выполнения.
Из проводника компилятора Godbolt:
uint32x4_t access(int idx) {
return CTRS[idx];
}
@ g++5.4 -O3 -Wall -mcpu=cortex-a53 -mfpu=neon -mfloat-abi=hard -std=gnu++11
access(int):
movw r3, #:lower16:.LANCHOR0
movt r3, #:upper16:.LANCHOR0 @ gcc chooses to construct the address with movw/movt
@ instead of loading from a literal pool when optimizing for cortex-a53
add r0, r3, r0, lsl #4
vld1.64 {d0-d1}, [r0:64]
bx lr
.section .rodata
.align 3
.set .LANCHOR0,. + 0 @@ equivalent to .LANCHOR0: here.
@@ Reference point that could be used for other .rodata objects if needed.
.type CTRS, %object
.size CTRS, 48
CTRS:
.word 1
.word 0
.word 0
.word 0
.word 2
.word 0
...
И MSVC -Ox: я понятия не имею, почему директиве MSVC DCQ все еще требуется 2 аргумента для создания одного 64-битного значения, точно так же, как DCD, если вы создаете массив int. Кажется, это отличается от Директива / псевдо-инструкция DCQ Кейла, где каждый аргумент является, разделенный запятыми, представляет собой 64-битное целое число.
Но, AFAICT, комментарии, добавленные MSVC, являются точным представлением числа для каждой строки.
;; ARM msvc19.14 -O2
.rdata
|__n128 const * const CTRS| DCQ 0x1, 0x0 ; = 0x0000000000000001 ; CTRS
DCQ 0x0, 0x0 ; = 0x0000000000000000
DCQ 0x2, 0x0 ; = 0x0000000000000002
DCQ 0x0, 0x0 ; = 0x0000000000000000
DCQ 0x3, 0x0 ; = 0x0000000000000003
DCQ 0x0, 0x0 ; = 0x0000000000000000
EXPORT |__n128 access(int)| ; access
.text$mn SEGMENT
|__n128 access(int)| PROC ; access
movw r3,|__n128 const * const CTRS|
movt r3,|__n128 const * const CTRS|
add r3,r3,r0,lsl #4
vldm r3,{d0,d1}
|$M4|
bx lr
ENDP ; |__n128 access(int)|, access
В C (но не C++) MSVC допускает синтаксис назначенного инициализатора
static const uint32x4_t CTRS[3] = { [0].n128_u32 = {1, 0, 0, 0}, [1].n128_u32 = {2, 0, 0, 0}, [2].n128_u32 = {3, 0, 0, 0} };
uint32x4_t access(int idx) {
return CTRS[idx];
}
Это прекрасно компилируется в режиме C MSVC, но не в C++. Вы можете использовать это для немного более перспективного определения INITu32x4, которое с шумом выйдет из строя, если что-то не так, и не сломается, если MS решит изменить порядок определения объединения.
Godbolt имеет режим языка C. Я обычно никогда не использую его (а просто использую -xc для g ++ / clang ++), потому что переключаться между ними неудобно, но я не знаю параметра командной строки, чтобы заставить MSVC компилироваться как C. В любом случае, это на Godbolt.