No video

What about Pointer Arithmetic with Void Pointers?

  Рет қаралды 17,568

Jacob Sorber

Jacob Sorber

2 жыл бұрын

Patreon ➤ / jacobsorber
Courses ➤ jacobsorber.th...
Website ➤ www.jacobsorbe...
---
What about Pointer Arithmetic with Void Pointers? // After my recent video about void pointers, some of you commented about pointer arithmetic. So, this is a follow-on video to address this issue. This video talks about why pointer arithmetic with void pointers should be avoided.
Related Videos:
Void Pointers: • The What, How, and Why...
Pointers and Arrays: • Arrays, Pointers, and ...
***
Welcome! I post videos that help you learn to program and become a more confident software developer. I cover beginner-to-advanced systems topics ranging from network programming, threads, processes, operating systems, embedded systems and others. My goal is to help you get under-the-hood and better understand how computers work and how you can use them to become stronger students and more capable professional developers.
About me: I'm a computer scientist, electrical engineer, researcher, and teacher. I specialize in embedded systems, mobile computing, sensor networks, and the Internet of Things. I teach systems and networking courses at Clemson University, where I also lead the PERSIST research lab.
More about me and what I do:
www.jacobsorbe...
people.cs.clem...
persist.cs.clem...
To Support the Channel:
+ like, subscribe, spread the word
+ contribute via Patreon --- [ / jacobsorber ]
Source code is also available to Patreon supporters. --- [jsorber-youtub...]

Пікірлер: 110
@oneletterz1659
@oneletterz1659 2 жыл бұрын
I'm not sure why every CS/ECE student doesn't follow you. I honestly can't imagine a better source of information than this channel.
@luz_reyes_676
@luz_reyes_676 2 жыл бұрын
Well. I found his variadic macro stuff a bit lack luster. He didnt really explain why there needs to be a named function parameter before the ellipsis. I found some other really good channel that explained. However, it was more dry. So dont let this be your one and only stop! (and he is really good. and VERY engaging, which I really enjoy)
@Yazan_Majdalawi
@Yazan_Majdalawi Жыл бұрын
What does ECE stand for?
@oneletterz1659
@oneletterz1659 Жыл бұрын
@@Yazan_Majdalawi electrical and computer engineering
@xr.spedtech
@xr.spedtech Жыл бұрын
He's focusing on the basics ... There's other ground to cover outside basics. So other channels... To meet other needs.
@Byynx
@Byynx Жыл бұрын
Superb i've learn for the first time what casting really means and even more about pointers. Thanks. ❤
@lonelymtn
@lonelymtn 2 жыл бұрын
Thanks for shouting out to us here in the Southern Hemisphere!
@ramadhanafif
@ramadhanafif 2 жыл бұрын
Your lessons has transformed my code, especially when it comes to optimization. Thanks a lot
@leokiller123able
@leokiller123able 2 жыл бұрын
I always increment void pointers directly when I want to add bytes (and I do that a lot in my programs) , I didn't know this was not standard, thanks for the info
@francescomazzucco6264
@francescomazzucco6264 2 жыл бұрын
I was doing that too, I find it dumb that there is no standard behaviour. Let +1 add one byte, simple and logical, at least to me
@Uerdue
@Uerdue 2 жыл бұрын
@@francescomazzucco6264 The most logical thing is to have the exact same behaviour as with all the other pointer types, i. e. add sizeof(void) when doing "+1". Then the question arises what the most logical value for sizeof(void) is...
@darioabbece3948
@darioabbece3948 2 жыл бұрын
@@Uerdue I think sizeof(void) should be u64 since addresses are that long
@Uerdue
@Uerdue 2 жыл бұрын
@@darioabbece3948 Well, `void` is not neccessarily meant to store addresses. `void*` is. And `sizeof(void*)` indeed equals the number of bytes of an address, so that's 8 or 4, depending on whether you're on a 64-bit or 32-bit machine.
@redcrafterlppa303
@redcrafterlppa303 2 жыл бұрын
@@darioabbece3948 I'm not sure but isn't sizeof(void) a compile error? Edit: I just checked and my C online compiler spit out 1. So as far as logic goes void* p; p += 1 Is equivalent to p += sizeof(void) ;
@anon_y_mousse
@anon_y_mousse 2 жыл бұрын
Doesn't look like anyone has taken me up on recommending you to learn C with, but I'm going to keep pushing people your way anyhow. Your channel is easily one of the top 5 for programming content, and certainly the number one channel for C.
@JacobSorber
@JacobSorber 2 жыл бұрын
Thanks. I appreciate it.
@ramakrishna4092
@ramakrishna4092 2 жыл бұрын
@@JacobSorber Hi sir I came across this question why can't we use "if or for or while outside I mean not in any function like globally I have tried to execute the below code but compiler don't allow to execute and I am getting an error which I have mentioned below // Online C compiler to run C program online #include if(1) { } int main() { // Write C code here printf("Hello world"); return 0; } This is the code error: expected identifier or '(' before 'if' 3 | if(1) | ^~ can you pls help me with this question .
@herohera3497
@herohera3497 Жыл бұрын
@@ramakrishna4092 what did u write if(1) just remove that function
@chrissaltmarsh6777
@chrissaltmarsh6777 2 жыл бұрын
Fascinating. A long time ago I drove hardware using pointers, that's what you did. You add 2 to a pointer, it is pointing 2 bytes up the line. You get your C code pointer numbers wrong, the code does something wrong. - it'll read the wrong value or write something horrid to your CAMAC. It was rather charming how the original C allowed you to really, really screw up.
@MoustafaRaafat2
@MoustafaRaafat2 2 жыл бұрын
Correction: You stated "The compiler didn't have to do something reasonable, because the C standard doesn't actually support this behavior, it doesn't make any guarantees". That's in fact not true. The C standard prohibits void pointer arithmetic, so this is not an undefined behavior, it's very clearly defined. However, having a compiler adding this feature as a "compiler extension" is something completely different than a UB (same goes for something like nested functions with GCC). Again GCC and other compilers have many extensions (that doesn't make your program undefined as you mentioned in your final words). But if you choose to be strictly compliant with the C standard, you may use some compiler flag like "-Werror=pedantic" and you're good to go.
@insu_na
@insu_na Жыл бұрын
learned this the hard way, way back when 😂 my assumption was that void pointers would always increment by the size of the compiler's integer, but nope. Been using char* since then
@nieczerwony
@nieczerwony 2 жыл бұрын
This is why I love C and low level. You shouldn't do it, but you are free to try. Full control.
@JacobSorber
@JacobSorber 2 жыл бұрын
Yeah, I agree. I think this is one of C's greatest strengths, as an education tool, whether or not we choose to use it for every project.
@redcrafterlppa303
@redcrafterlppa303 2 жыл бұрын
I was inspired by your void pointer video to build a pointer type in java that works on native memory. While writing the classes I stumbled over this exact problem, "what should p.add(int i) do on a void type." I thought it must be 1 byte but how does languages with pointers do it? And now I have my answers, they don't know it either XD. Thanks for the video.
@JacobSorber
@JacobSorber 2 жыл бұрын
You're welcome. Glad I could help.
@abdallahmah1867
@abdallahmah1867 Жыл бұрын
will get it. Just don't get burnt out. Whenever you need a break, take one.
@keesterwee4890
@keesterwee4890 2 жыл бұрын
Excellent as always! What puzzels me that it is possible to define an array of void pointers. That means that there must be a size of a void pointer otherwise indexing such an array would be difficult
@JacobSorber
@JacobSorber 2 жыл бұрын
Void pointers do have a size (all pointers have the same size). The problem with pointer arithmetic is that we don't know the size of the thing that the pointer points to.
@keesterwee4890
@keesterwee4890 2 жыл бұрын
@@JacobSorber clear, i get the point
@evan_game_dev
@evan_game_dev 2 жыл бұрын
One thing I might add is that everyone should turn up their warning levels when they compile (I have level4 set when using msvc from the command line). When you do that, it doesn't even let you do pointer arithmetic on void pointers
@laxmikantbotkewar4191
@laxmikantbotkewar4191 2 жыл бұрын
That font looks so nice how to set it up ?? plus what colour theme, file icon theme and product theme you use ?? I am learning a lot from you as a Embedded student your videos help a lot to understand C/OS concepts thank you.
@thefossenjoyer3346
@thefossenjoyer3346 2 жыл бұрын
I think the font is Menlo, but I'm not sure
@starc0w
@starc0w 2 жыл бұрын
Great! Thank you very much!
@nexovec
@nexovec 2 жыл бұрын
nice, I actually didn't know that's all UB
@beardlyinteresting
@beardlyinteresting 2 жыл бұрын
You know, I'd always assumed that compilers wouldn't allow you to do void pointer arithmetic so I never thought to even try it. I mean as you said void doesn't have type information so you have no guarantees it would do anything remotely sane. But I guess compilers allowing you to do that is pretty C.
@viacheslav1392
@viacheslav1392 2 жыл бұрын
Good try to avoid UB ! However You still have ONE on the 22 line !)
@georgecop9538
@georgecop9538 2 жыл бұрын
We should talk more about hexspeak and what OSes uses it.
@Byynx
@Byynx Жыл бұрын
Can you explain why in some directx and and opengl functions they ask for void pointers args, when the type of data the pointer is pointing to is always the same i guess? Is it because they wanna treat that arg as different datatypes?
@SlideRSB
@SlideRSB 2 жыл бұрын
What about sizeof(void)? What would that evaluate to?
@ajinkyakamat7053
@ajinkyakamat7053 2 жыл бұрын
It's a compile error as per C89. It's an incomplete type and u can't take the size of an incomplete type. Just like u can't take the sizeof a forward declared struct. But gcc will compile it for you. And it will be equal to sizeof(char).
@Uerdue
@Uerdue 2 жыл бұрын
On GCC, sizeof(void) is typically 1. So, having the pointer arithmetic treat "+1" as "make the pointer point to the address 1 byte higher" is at least consistent with that. (Edit: Ajinkya was faster, and more precise.)
@zxuiji
@zxuiji 2 жыл бұрын
Personally I think that since void is size 0 (as a result of no type info) pointer arithmetic with it should just result in addr + 0 * 2
@Uerdue
@Uerdue 2 жыл бұрын
That would kinda make sense, but GCC seems to define sizeof(void) as 1, so at least it's consistens there.
@zxuiji
@zxuiji 2 жыл бұрын
@@Uerdue That might be due to how it implements types under the hood, it might use division with it somewhere and to avoid checking for 0 they just default the size to 1, so in that sense I can understand it being 1 instead of 0
@JaimeWarlock
@JaimeWarlock Жыл бұрын
I think since C is an evolution of assembly code in the early days that most engineers saw an increment of an address/data as adding one. The exception were commands that would both load data and increment/decrement and address. These would do so according to the size of the data.
@unperrier5998
@unperrier5998 2 жыл бұрын
void* pointer arithmetic. My god, who had this crazy idea in the first place? Semantically it'd not defined at all. It should not compile, at least not without a warning.
@ohwow2074
@ohwow2074 2 жыл бұрын
Even with -Wall there is no warning. I guess he has to turn on -Wpedantic for that.
@anon_y_mousse
@anon_y_mousse 2 жыл бұрын
Would've been funny if it had been a nop instead, like void *v = &foo; v += 1; would equate to (void); and then be really weird and make dereferencing just return 0 every time. As in int i = *v; would result in i being set to 0 even if foo is an int and points to 47.
@unperrier5998
@unperrier5998 2 жыл бұрын
@@anon_y_mousse rather than define a behaviour that feel odd to most of us, it's better not to allow void* arithmetic in the first place.
@anon_y_mousse
@anon_y_mousse 2 жыл бұрын
@@unperrier5998 No, I meant comical funny, not odd funny. Especially if it issued no errors or warnings.
@justcurious1940
@justcurious1940 Жыл бұрын
does not compile in c++
@marcotulioalvesdebarros518
@marcotulioalvesdebarros518 2 жыл бұрын
Hey, could you do a video on AVL Trees, please?
@codegodtreviso4448
@codegodtreviso4448 2 жыл бұрын
What are your thoughts on the zig programming language
@Sakuraigi
@Sakuraigi 6 ай бұрын
I just wrote that exact comment on the other video then this video showed up for me 😂
@georgecop9538
@georgecop9538 2 жыл бұрын
Would be cool to talk about TCC
@michaelclift6849
@michaelclift6849 2 жыл бұрын
What's the worst bug you've ever faced? Is there one in particular that's memorable? I'd be interested to hear why you made it, and what steps you took to avoid repeating it. Maybe there's more than one?
@JacobSorber
@JacobSorber 2 жыл бұрын
Good question. I'll have to think about this one. Might be an interesting topic for a future video.
@michaelclift6849
@michaelclift6849 2 жыл бұрын
I've been developing uC products since my teens (I'm 46 now) I have a killer story which inspired this question, but I'm no youtuber.
@JacobSorber
@JacobSorber 2 жыл бұрын
@@michaelclift6849 Well, if you were to send it to a youtuber they might enjoy it and they might even include it in a video.
@michaelclift6849
@michaelclift6849 2 жыл бұрын
@@JacobSorber It may be difficult to include in a video, but here's what happened. Please confirm if you can access the link ok: drive.google.com/drive/folders/1pJGpEQ5IZGpaHYbHW4hzJ995pMUcP2PH?usp=sharing
@gloverelaxis
@gloverelaxis 2 жыл бұрын
Why on earth does C give the `+` operator this special, implicit, behaviour when it's operating on pointers? That just sounds like a recipe for confusion and bugs. Why doesn't C just say that pointers aren't valid arguments for arithmetic functions? This way, it would force you to treat addresses as ordinary unsigned integers with explicit casts, and then use `sizeof` to line up your arithmetic with the size of the objects being stored.
@monochromeart7311
@monochromeart7311 2 жыл бұрын
The main reason is alignment I believe. Pointers to type T where T is a POD, must be aligned to sizeof(T) bytes. int x = 0; int *p = &x; ((char*)p) += 1; *p = 10; //undefined behavior! Assuming an _int_ is 4 bytes, *p* must have a value that is divisible by 4. Functions like *memset* which use _long int_ pointers to access memory faster, must first make sure the pointer is divisible by *sizeof(long int)* and only then do the fast access (they access the unaligned bytes using a _char_ pointer). So to avoid trivial bugs, addition on a pointer will not break the alignment. With your idea, compilers will probably issue warnings about alignment, which means people will use *sizeof* anyways, so why not make it a rule of the language anyways.
@Uerdue
@Uerdue 2 жыл бұрын
Because it happens often enough that people would be annoyed to have to write the additional `* sizeof(foo)` all the time. Plus, it would make your code less maintainable. Because suddenly, when you try to use the same code for handling the "bar" type instead of "foo", you have to change the `sizeof(foo)` to `sizeof(bar)` everywhere... (And then you miss it one time and it makes for a very hard-to-find bug...) One could maybe argue that having a *different* notation that is less prone to be confused with regular addition would be nicer. And in fact, there is one, namely `&(ptr[i])`. That's even more ugly, though... :D
@anon_y_mousse
@anon_y_mousse 2 жыл бұрын
@@monochromeart7311 What you're talking about with memset is an implementation detail that won't be shared with every implementation. With SSE it may access memory at offsets divisible by 16 bytes and even on 64-bit platforms it could still be implemented to deal with 1 byte at a time as the standard requires nothing more extravagant. Also, misaligned pointers aren't even necessarily slower on platforms that allow them which is most these days. Try this on your own computer: int a[3] = { 0 }; int *p = ( char * ) a + 5; *p = 123; // It's technically UB but will still compile and run without errors, though it should generate a warning, depending on the compiler you're using. And will actually generate an error if you set the right flags with your compiler.
@monochromeart7311
@monochromeart7311 2 жыл бұрын
@@anon_y_mousse the issue I'm talking about is UB due to misalignment, that's all. All mem___ implementations I've seen work on word-sized memory for faster access (it's a common optimization), which is int/long on most platforms. The values at locations not divisible by the word size will be accessed using char pointers.
@anon_y_mousse
@anon_y_mousse 2 жыл бұрын
@@monochromeart7311 In this specific instance, it's possibly UB due to both misalignment and type mismatch due to the cast, and in other instances would certainly be both if you weren't just using int's, and I did say in my post that it's UB. However, it won't fail to execute and indeed correctly. Give it a try.
@mihaeldimoski
@mihaeldimoski 2 жыл бұрын
how to avoid structure padding?
@Uerdue
@Uerdue 2 жыл бұрын
Declare the struct with `__attribute__((packed))`.
@mihaeldimoski
@mihaeldimoski 2 жыл бұрын
@@Uerdue yes, but will affect the performance of the program
@mohad12211
@mohad12211 2 жыл бұрын
@@mihaeldimoski structure padding is there so that the cpu can be fast fetching memory, if the structure is not padded then cpu won't fetch memory fast, how do you want the cpu to fetch your structure fast if it's not padded correctly? simply not possible, you can't have it both ways
@sanderbos4243
@sanderbos4243 2 жыл бұрын
You can reorder your struct's members, look up the page "The Lost Art of Structure Packing"
@anon_y_mousse
@anon_y_mousse 2 жыл бұрын
There's no one way of doing it that's standard compliant. Using the __attribute__((packed)) method will work in GCC, but not in MSVC. However, one can use #pragma pack(push,1) before your struct and then #pragma pack(pop) after it to get the same behavior in both MSVC and GCC. In other compilers, it likely differs.
@rubyciide5542
@rubyciide5542 7 ай бұрын
The real problem with understanding pointers is that people are coming from these languages that have a lot of abstraction If you were a programmer in the early days and you come from assembly this will all make sense to you compared to a guy from js or python
@maqusss
@maqusss 2 жыл бұрын
how come sizeof(int*) = 8 but ip+2 increased by 8 instead of 2*8 ? (5:43)
@stefan-danielwagner6597
@stefan-danielwagner6597 2 жыл бұрын
The size of a pointer is the size of a word of memory, it will be 8 bytes for all 64-bit machines for any datatype you have a pointer to. The size of the datatype, that is the size when it would be dereferenced, in your case int, is 4. This is the case for any other datatype, just think about an array, any element is at offset i*sizeof(element[0]).
@sanderbos4243
@sanderbos4243 2 жыл бұрын
Because the +2 will look at the size of the pointed to type, which is the int in this case
@maqusss
@maqusss 2 жыл бұрын
@@stefan-danielwagner6597 Thanks for explanation, i get it now.
@olafgunther9401
@olafgunther9401 Жыл бұрын
00:16 mister world wide
@luciuscato4859
@luciuscato4859 2 жыл бұрын
Pointers: a heap of trouble
@didiTchu
@didiTchu 2 жыл бұрын
why dont you use clion
@JacobSorber
@JacobSorber 2 жыл бұрын
Why don't you use vim? 🤔 I have a video where I talk about IDEs. That might help clarify a bit. At some level, it's just personal preferences and what I think will be most helpful for my students.
@nexasdf
@nexasdf 2 жыл бұрын
Cool! :)
@lissettevelec8718
@lissettevelec8718 Жыл бұрын
you are good professor but I really wish I can afford the C course, its a hundred dollars I am broke student.. I wish can be more affordable one course at a time for students.
@JaimeWarlock
@JaimeWarlock Жыл бұрын
There is plenty of online stuff to learn C for free. Code::Blocks is free and I use it for all my work.
@lissettevelec8718
@lissettevelec8718 Жыл бұрын
@@JaimeWarlock Blocks? please send the proper channel I can follow there is thousands of them but only theory, not consistant.
@saumyacow4435
@saumyacow4435 Жыл бұрын
In my years as a C programmer, I never used void*. It's one of a bunch of things in the C language that I never used, on principle. Because it's stupid.
@benjaminbawkon8040
@benjaminbawkon8040 Жыл бұрын
You've never used malloc? Because that returns a void*
@18bansalaman
@18bansalaman 2 жыл бұрын
Hey, is carbon going to kill c?
@emiliachan
@emiliachan 2 жыл бұрын
nope! one of the reasons its an llvm language and not compiled into byte code
A const int is not a constant.
9:16
Jacob Sorber
Рет қаралды 67 М.
Can I write to NULL (0x0000000000) without seg faulting?
6:59
Jacob Sorber
Рет қаралды 29 М.
Logo Matching Challenge with Alfredo Larin Family! 👍
00:36
BigSchool
Рет қаралды 7 МЛН
小蚂蚁被感动了!火影忍者 #佐助 #家庭
00:54
火影忍者一家
Рет қаралды 53 МЛН
My Cheetos🍕PIZZA #cooking #shorts
00:43
BANKII
Рет қаралды 24 МЛН
Are Lists Evil? Creator Of C++ | Prime Reacts
14:30
ThePrimeTime
Рет қаралды 98 М.
Void Pointers | C Programming Tutorial
12:44
Portfolio Courses
Рет қаралды 9 М.
Pulling Back the Curtain on the Heap
21:38
Jacob Sorber
Рет қаралды 36 М.
Make your Data Type more Abstract with Opaque Types in C
13:41
Jacob Sorber
Рет қаралды 49 М.
Is memcpy dangerous?
14:08
Jacob Sorber
Рет қаралды 23 М.
Making variables atomic in C
11:12
Jacob Sorber
Рет қаралды 36 М.
but what is 'a lifetime?
12:20
leddoo
Рет қаралды 68 М.
When do I use a union in C or C++, instead of a struct?
11:18
Jacob Sorber
Рет қаралды 68 М.
How do I access a single bit?
11:07
Jacob Sorber
Рет қаралды 20 М.
Compiled Python is FAST
12:57
Doug Mercer
Рет қаралды 106 М.