Approved: ASR Pro
Speed up your computer’s performance now with this simple download.
Over the past few weeks, some readers have encountered an error code with a void pointer, which is used for arithmetic errors. This problem occurs due to several factors. Now we will deal with them.
Requested
Visited 28000 times
I have experience writing and reading registers from crammap like this:
// READreturn * ((volatile uint32_t *) (roadmap + offset));// WRITE* ((volatile uint32_t *) (location + offset)) = value;
Warning: hint like "void *" used in math [-Wpointer-arith]
How do I change the code that suppresses warnings? I am using C ++ and Linux.
requested November 5, 2014 at 11:04 am
1321
Not The Answer You Are Looking For? Scroll Through Other Questions Tagged With C ++ Pointers, Null Pointer, Pointer Arithmetic, Or Ask Your Own Question.
Approved: ASR Pro
ASR Pro is the world’s most popular and effective PC repair tool. It is trusted by millions of people to keep their systems running fast, smooth, and error-free. With its simple user interface and powerful scanning engine, ASR Pro quickly finds and fixes a broad range of Windows problems — from system instability and security issues to memory management and performance bottlenecks.
Since void *
is a valid pointer to an unknown type, you cannot perform pointer arithmetic because the compiler does not explicitly know the size of the object that the reference points to.
The best way to do this is to help you convert map
to a type, which was then one byte wide, and do some arithmetic. For many of them you can use uint8_t
:
// READreturn * ((volatile uint32_t *) (((uint8_t *) map) + cancel));// WRITE* ((volatile uint32_t *) (((uint8_t *) map) + decrease)) = value;
654
Answered Nov 5, 2014 11:34 am
56.6k
The void type is an incomplete type. Its size is unknown. So show that the math with the clues to the vacuum doesn’t really make sense. You must cast a pointer that is returned to type void to a pointer of a different type. An example of a pointer can be written char.Also note that clients are not allowed to assign an object declared using the volatile qualifier.
answered Nov 14, 14 at 11:14
231,000
If the way to useI arithmetic for null recommendations is really what you need, since computation is made possible by GCC (see Arithmetic for null pointers and function pointers), you can use -Wno-pointer-arith <. use / code> to suppress the warning.
answered Jan 21 '15 at 11:20
164
Speed up your computer's performance now with this simple download.
Related Posts:
- Correct And Correct Address And Envelope Printing In Outlook…
- How To Fix C.defaultview.getcompputedstylea Null Is Null…
- Steps To Resolve Already Used Jboss Jvm_bind Error Addresses
- Steps To Correct The Absolute Calculation Error
- Steps To Correct A Printing Error Message
- Steps To Correct An Error In The Preun Scriptlet
Все операции с void * кроме приведения типа уже UB. Сделай хотя бы (*(int32_t *)(buffer))++
- Показать ответ
- Ссылка
Ответ на:
комментарий
от sambist 06.02.15 07:59:38 MSK
См. параграф стандарта 6.5.6 Additive operators
Стандарт определяет семантику только для случаев, когда указатель указывает на массив элементов типа T.
Поскольку указатель типа void * не может указывать на массив (т.к. элемент с типом void невозможен), можно сделать вывод, что семантика не определена.
Deleted
(06.02.15 08:39:42 MSK)
- Показать ответ
- Ссылка
Как я помню, указатель на void должен вмещать в себя самый длинный из указателей целевой платформы. Т.е. для 32-битной void* будет шириной в 32 бита, для 64-битной — 64.
- Ссылка
Ответ на:
комментарий
от Deleted 06.02.15 08:39:42 MSK
Поскольку указатель типа void * не может указывать на массив (т.к. элемент с типом void невозможен), можно сделать вывод, что семантика не определена.
не совсем так. Void* это костыль для полиморфизма в сишке. Ну например для того, что-бы реализовать malloc(3). Функция malloc(3) как раз и возвращает void*, и это вполне реальный и валидный указатель.
Я понимаю, что это плохо, но иначе никак. Подразумевается, что размер одного «элемента» void* равен 1 char’у, хотя конечно этот «элемент» фиктивный.
Похожая история с указателем на элемент массива, сразу за последним, он допустим, только его нельзя разыменовывать.
int a[10];
int* ptr = &(a[10]);// так можно
*ptr;// а так уже нельзя
ptr = &(a[11]);// так тоже нельзя, UB
emulek ★
(06.02.15 09:42:39 MSK)
- Ссылка
Ответ на:
комментарий
от dnf83 06.02.15 09:47:01 MSK
Ответ на:
комментарий
от emulek 06.02.15 09:50:14 MSK
По стандарту положено ptrdiff_t для хранения разницы двух указателей. А операция вычитания определена только для операторов указывающих на один и тот же массив.
- Показать ответ
- Ссылка
Ответ на:
комментарий
от kim-roader 06.02.15 10:10:57 MSK
По стандарту положено ptrdiff_t для хранения разницы двух указателей.
любые другие операции с указателями, кроме вычитания, это UB.
А операция вычитания определена только для операторов указывающих на один и тот же массив.
в принципе да.
Тут вопрос к ТСу, на кой ляд ему это вычитание понадобилось-то? Пусть скастует свой void* в то, что это на самом деле, и вычитает.
например
uint8_t* buffer = getBuffer();
ptrdiff_t offset = 17;// тут можно size_t
buffer += offset;
на кой ляд делать буфер хрен знает чего?
emulek ★
(06.02.15 10:20:28 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от emulek 06.02.15 10:20:28 MSK
Тред не читай&сразу отвечай.
С UB разобрались.
Остался вопрос про ядро.
Deleted
(06.02.15 10:33:15 MSK)
- Показать ответы
- Ссылка
Ответ на:
комментарий
от Deleted 06.02.15 10:33:15 MSK
Тред не читай&сразу отвечай.
если ты про
Мне не писать, мне обоснование чтобы мочить.
то основание у тебя уже есть, без арифметики, достаточно void *buffer = getBuffer(), потому что нет смысл выделять буфер, который невозможно использовать для хранения информации.
Остался вопрос про ядро.
в ядре какой-то другой стандарт?
emulek ★
(06.02.15 10:42:03 MSK)
- Ссылка
Ответ на:
комментарий
от Deleted 06.02.15 10:33:15 MSK
Тебя не пустят в ядро с UB. Даже с подозрением на UB.
- Ссылка
компиляторы это пропускают
gcc у меня вот так ругается
warning: pointer of type 'void *' used in arithmetic
обрабатывают адекватно
Как понять «адекватно» в случае UB? Вот у меня перемещает указатель на offset байт.
Второй вопрос — пропускают ли подобный код в ядро?
Руки бы оторвать за такое. Больше потенциальных багов в ядре!
А главное, нахрена? Если ты сдвигаешь указатель куда-то, значит, ты знаешь, на сколько байт ты хочешь его сдвинуть. Кастани в char* и двигай себе.
grondek ★
(06.02.15 10:47:46 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от Deleted 06.02.15 10:33:15 MSK
Это не UB. Это запрещено в современном С (illegal), но некоторые компиляторы еще разрешают, с sizeof(void) == 1
anonymous
(06.02.15 10:51:14 MSK)
- Ссылка
Ответ на:
комментарий
от grondek 06.02.15 10:47:46 MSK
значит, ты знаешь, на сколько байт ты хочешь его сдвинуть. Кастани в char* и двигай себе.
лучше в uint8_t*, вообще-то char не обязан быть байтом из 8и битов.
Это не UB.
это не UB, UB неизбежно будет ниже по коду.
emulek ★
(06.02.15 10:55:53 MSK)
- Ссылка
Ответ на:
комментарий
от Deleted 06.02.15 11:12:20 MSK
Ответ на:
комментарий
от anonymous 06.02.15 13:02:31 MSK
это расширение gcc
Ага. Тогда повторю уже прозвучавший тут вопрос — а зачем так делать?
код такой в ядре есть
Ну надо же. Оказывается и от анонимуса польза есть.
Deleted
(06.02.15 14:29:44 MSK)
- Показать ответ
- Ссылка
#define MAKEPTR(type,base,offs) ((type)((uintptr_t)(base)+(uintptr_t)(offs)))
anonymous
(06.02.15 17:12:44 MSK)
- Ссылка
На практике всегда было как с char*.
anonymous
(06.02.15 17:26:06 MSK)
- Ссылка
sizeof void в C равен sizeof char. в C++ не определён как sizeof неполного типа
jtootf ★★★★★
(06.02.15 23:23:00 MSK)
- Показать ответ
- Ссылка
Ответ на:
комментарий
от jtootf 06.02.15 23:23:00 MSK
sizeof void в C равен sizeof char
В C он не определён. Равен sizeof char — это тоже расширение гцц.
Deleted
(07.02.15 02:54:09 MSK)
- Ссылка
Ответ на:
комментарий
от anonymous 06.02.15 13:02:31 MSK
Огорчу я тебя невероятно. Арифметика с void * это расширение gcc, и код такой в ядре есть, см http://lxr.free-electrons.com/source/lib/bsearch.c
я всегда не понимал разработчиков, которые ради функции в десять строк обмазываются callback указателями. Особенно учитывая, что в большинстве случаев этот callback является обёрткой к какой-нить strcmp(3) или вообще к вычитанию двух целых чисел.
emulek ★
(07.02.15 12:01:59 MSK)
- Ссылка
Ответ на:
комментарий
от Deleted 06.02.15 14:29:44 MSK
Ага. Тогда повторю уже прозвучавший тут вопрос
в данном случае это полиморфизм: использования массива из хрен знает чего. Ну и тут в функцию передаётся указатель на другую функцию, которая это хрен знает что сравнивает. Если совсем упарываться, то для полноты нужна ещё одна callback, что-бы переходить к следующему эл-ту коллекции. Но вот тут сэкономили немножко, передав размер хрен знает чего.
emulek ★
(07.02.15 12:13:09 MSK)
- Ссылка
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.
Contents
Overview
These C compile/build errors and warnings are talked about largely in relation to embedded systems (i.e. microcontrollers).
“pointer of type void used in arithmetic”
Usually occurs when you are doing memory arithmetic, and can actually be a warning you ignore!
|
|
“elf section ‘.bss’ will not fit in region ‘ram’
C build error ‘elf section ‘.bss’ will not fit in region ‘ram’
The .bss section contains all 0-initialized global and static variables. This error normally occurs when you have overly large static variables, or you haven’t allocated the stack/heap sizes correctly.
“Suggested parenthesis around assignment used as a truth value”
A warning message from the C compiler.
This is usually because you’ve forgotten to add the second =
in the if statement.
|
|
“Subscripted value is neither array nor pointer”
The C build error ‘subscripted value is neither array nor pointer’.
Normally occurs when you try and index something like an array which isn’t. For example…
|
|
“#pragma once in main file”
The C compiler warning ‘#pragma once in main file’ which occurs when the directive ‘#pragma once’ is incorrectly placed in a .c file.
This occurs when you incorrectly write “#pragma once” in a .c file (even though the error would suggest it, it doesn’t have to be main.c). “#pragma once” is a header guard which prevents an .h file from being included twice in a project and causing multiple declaration/definition errors. Hence “#pragma once” should be only place in .h files. It is an alternative to the “#ifndef” header guard style (see this page for more info).
“variable or field declared void”
The C build error ‘Variable or field declared void’.
This can occur when you declare/define a function in C++ and the compiler doesn’t recognise one of the data types used for an input variable. It will precede a <variable> was not declared in scope
error.
|
|
“macro names must be identifiers”
If you get the error macro names must be identifiers it is usually because you have been using both #if()
and #ifdef
directives, and accidentally used the combination #ifdef()
. This is not allowed! When using #ifdef
, do not enclose the proceeding identifier with brackets.
|
|
“Not In Formal Parameter List”
The ‘not in formal parameter list’ build error is most likely to occur when you have forgotten to add the semi-colon at the end of a function declaration.
Applies To: Keil C51 Compiler
The “not in formal parameter list” build error is most likely to occur when you have forgotten to add the semi-colon at the end of a function declaration. Without the semi-colon, the compiler continues to read onto the following lines, and usually produces this error. Check the first first function declaration preceding this error for a missing semi-colon.
|
|
double free or corruption
Error Type: Run Time
This error normally codes with another keyword at the end, e.g.
|
|
It normally occurs when you accidentally free()
the same piece of memory twice. I have also got this error due to a incremental-build bug in the Xilinx SDK (xsdk) for it’s Zynq FGPAs/microcontroller chips.