|
C pointer arithmetic always operates in whole-element units. In lower-level terms, it's already scaled by the size of the element type. So in your original example:C++ code:
But if you have any control over this header at all, I would really recommend that you introduce a struct: C++ code:
C++ code:
|
# ? Dec 3, 2019 00:03 |
|
|
# ? Jun 7, 2024 06:50 |
|
rjmccall posted:Don't worry, this is a very common misunderstanding for people starting from a hardware-centric perspective. I mean I used to write in C and to a much, much lesser extent C++, but it's method of handling pointers, including syntax always does my head in. quote:There's a more modern way of doing this if you can use C11 / C++11, but I don't want to make any assumptions about embedded toolchains. According to the documentation it implements a decent subset of C99. So, no. It's not embedded but the toolchain is commercial. Because of the end result of legacy it's incredibly difficult to avoid using it for initial boot and HAL. I tried that a couple of years ago using GCC. Not impossible (I think) but beyond my ability. It's a multi-faceted issue that has a nasty habit of propagating. Really surprising because the boot / HAL code is built as a separate binary then incorporated into the main image. But that's all beside the point. I'd love to use a struct with a sprinkling of unions as an access method for the static workspace. In fact I'm pretty sure it'd work perfectly. The problem is maintainability. If the format of the static workspace is changed, the struct is accessing incorrect data unless it's updated by hand to match. While I hate using a big header full of #defines, it can be autogenerated from a script via the makefile if necessary.
|
# ? Dec 3, 2019 00:32 |
|
If you can autogenerate a header full of defines, you can autogenerate static asserts that will make sure your struct is accessing the right locations (and tell you to update it if it isn't).
|
# ? Dec 3, 2019 01:34 |
|
Jabor posted:If you can autogenerate a header full of defines, you can autogenerate static asserts that will make sure your struct is accessing the right locations (and tell you to update it if it isn't). "I" would be an ancient perl script that somebody wrote that performs the magic. I just give it an input and output file and try to make sure none of the errors change the alignment. It's mostly just lines the script doesn't understand.
|
# ? Dec 3, 2019 05:03 |
|
I never really write tmp stuff, is this ostream overload to print, comma separated, any type with const iterators cool or is it dumbcode:
|
# ? Dec 6, 2019 04:41 |
|
I think it's easier to just print the first element and then iterate over the rest of the sequence printing a comma followed by the current element. That's one iterator and a simpler loop.
|
# ? Dec 6, 2019 05:03 |
|
MutantBlue posted:I think it's easier to just print the first element and then iterate over the rest of the sequence printing a comma followed by the current element. That's one iterator and a simpler loop. that would be better, yeah.
|
# ? Dec 6, 2019 05:20 |
|
Dren posted:I never really write tmp stuff, is this ostream overload to print, comma separated, any type with const iterators cool or is it dumb I kind of dislike the idea of overloading operator<< with a template like this. I feel like it it would be an overload collision waiting to happen. It sucks from an operator chaining perspective but actually naming the function something like outputAsCommaSeparatedList would be better I think. You could also write it as a function that doesn't take an ostream but returns a std::string instead so that you could still chain <<. The std::string version has the advantage of being more flexible as well, since there may be situations where you do not want to create an ostream just to turn this into a std::string. - Using std::begin() and std::end() are probably better from an extendability standpoint as well. - I think the function would be clearer if you did the comma differently. It's kind of confusing what was going on. There's a ton of ways to skin this cat but the following is pretty clear I think: code:
Captain Cappy fucked around with this message at 05:29 on Dec 6, 2019 |
# ? Dec 6, 2019 05:24 |
|
Notably, std::string provides cbegin(), so this template will compete with the standard operator<<. It will probably lose on account of being less specialized — but then again it might not, because the standard operator<< is probably templated over the character type, so this will in fact be more specialized in at least one argument.
|
# ? Dec 6, 2019 07:55 |
|
Potentially a better way to do this is to write a function that takes in your iterator, and returns something that would print the joined result when you write it to an ostream. So you would use it like:code:
In the simplest case you could just return a string (which would also make this useful in non-ostream contexts), but if you profiled things and determined that the extra allocation was unacceptable for your application then you could also return a custom type that just records the arguments, with an overloaded operator<< that actually does the work.
|
# ? Dec 6, 2019 08:07 |
|
Jabor posted:Potentially a better way to do this is to write a function that takes in your iterator, and returns something that would print the joined result when you write it to an ostream. So you would use it like: This, because your implementation is nowhere near constrained enough.
|
# ? Dec 6, 2019 10:30 |
|
Pointer arithmetic follows its sizeof(*ptr), so 32 bits to answer the question. Use a char* if the offsets are in bytes. Edit: img-timelined myself
|
# ? Dec 6, 2019 10:57 |
|
Captain Cappy posted:I kind of dislike the idea of overloading operator<< with a template like this. I feel like it it would be an overload collision waiting to happen. rjmccall posted:Notably, std::string provides cbegin(), so this template will compete with the standard operator<<. It will probably lose on account of being less specialized but then again it might not, because the standard operator<< is probably templated over the character type, so this will in fact be more specialized in at least one argument. You guys are correct. As implemented in my first post, a cout of a std::string is a collision. code:
Jabor's suggestion of a join function makes way more sense and is how this sort of thing is typically done anyway. I wrote a join function i/o manipulator but it didn't work since the relevant ostream overload is for an actual function pointer, not a std::function. So I added an overload for a std::function and it's all good: code:
Dren fucked around with this message at 17:29 on Dec 6, 2019 |
# ? Dec 6, 2019 16:28 |
|
I have 2 questions that I'd really love an answer to: 1. For nlohmann::json library, how would one go about defining an operator== for the float type (json::number_float_t which now is a double) so that it does an epsilon comparison (like they have in the documentation), but without actually changing json.hpp 2. Google's protobuf library has this class method definition: code:
code:
Now, I'd like to move this call into another method, still templated, but I would like the template to not be of enum google::protobuf::internal::WireFormatLite::FieldType type, but a different enum or an int that can be converted to the WireFromatLite::FiledType type. essentially, instead of: code:
code:
Why? Because I would like to not include "google/protobuf/wire_format_lite_inl.h" in my header file and still declare readPrimitive there as a member of the class. As it stands the only way to achieve what I want is to declare and implement readPrimitive as a standalone function in the compilation unit. It works, but I was wondering if there is a better option. I tried even with variadic templates, no luck: code:
|
# ? Dec 15, 2019 05:47 |
|
Volguus posted:I have 2 questions that I'd really love an answer to: Don't. Having a non-transitive operator== is a terrible idea. And regardless, you can't reasonably judge whether two floats are "close enough" to being the same without knowing what went in to producing those values. Volguus posted:2. Google's protobuf library has this class method definition: You've seen the code:
If you're just looking for ways to read VarInts and stuff, why not just directly use the methods on CodedInputStream?
|
# ? Dec 15, 2019 07:45 |
|
Jabor posted:Don't. Having a non-transitive operator== is a terrible idea. That is correct for a library like json. An application, a user of said library, can however make that call. I know what went into producing those values, and I know I can say float a and b are the same if abs(a-b)<some arbitrary value. Why do I wanna do this? So I can say ASSERT_EQ(json1,json2) in my unit test. Can I just loop through the values and compare each, doing the appropriate thing for float values? Sure, but what's the fun in that? Jabor posted:
Yes I have seen that, yes I am aware of it, it was a conscious decision that I made. Should it in the future became untenable to maintain my code given the speed of the changes google implements to these classes, I will revisit my decision. For now, it serves my needs perfectly. I do use CodedInputStream where it can be used. As you probably know, the 2 classes go well hand in hand, but are not a duplicate of each other. They do different things. I suspect they do not, however, make changes that often to those APIs, since they are being used by the generated classes. I could be wrong, only time will tell. This is a personal project, born out of not doing advent of code this year. I am and will be the sole developer and user of said project. The aim is to be able to take a proto file and a data file (xml, json, yaml) and produce a binary protobuf message that can be sent over to a consumer (http, websocket, plain socket) with the further away goal of being able to invoke gRPC methods, if even possible. Of course, it makes sense that if I can write a protobuf message, I should be able to read one as well and produce some data file (xml, json, yaml).
|
# ? Dec 15, 2019 17:17 |
|
Volguus posted:Why do I wanna do this? So I can say ASSERT_EQ(json1,json2) in my unit test. Can I just loop through the values and compare each, doing the appropriate thing for float values? Sure, but what's the fun in that? I'd think the right thing here would be something like AssertThat(json1, ApproximatelyEquals(json2, optionalThresholdWithReasonableDefault)) (Proto MessageDifferencer already has this option, though for some reason the threshold isn't configurable: https://developers.google.com/proto...yEquals.details ) Ah, it's there in matchers though: https://github.com/google/nucleus/blob/master/nucleus/testing/protocol-buffer-matchers.h code:
roomforthetuna fucked around with this message at 17:46 on Dec 15, 2019 |
# ? Dec 15, 2019 17:43 |
|
roomforthetuna posted:Aren't you already looping through the values and comparing each, as part of that equality assertion? Well yes, the operator== does that which is invoked by the ASSERT_EQ. I'm not quite sure how would a protobuf MessageDifferencer help me when comparing json objects.
|
# ? Dec 15, 2019 17:49 |
|
Volguus posted:Well yes, the operator== does that which is invoked by the ASSERT_EQ. I'm not quite sure how would a protobuf MessageDifferencer help me when comparing json objects.
|
# ? Dec 15, 2019 18:55 |
|
Volguus posted:1. For nlohmann::json library, how would one go about defining an operator== for the float type (json::number_float_t which now is a double) so that it does an epsilon comparison (like they have in the documentation), but without actually changing json.hpp I’d also note that what some epsilon documentation does not note is that you always need TLC with greater than and less than operators: if a ~= b then a > b or a < b may also be true. You must always invoke the epsilon comparison first and thus also override the “>” and “<“ operators for a correct result.
|
# ? Dec 15, 2019 19:28 |
|
Sorry if this is somewhat offtopic, but I have a wacky side project where I'm trying to make some nice library of "standard" algorithms and utility functions for a niche, domain-specific language. Its a functional programming language and wholly unrelated to C++ (well, the interpreter itself is implemented in C++, but I'm not talking about altering the language, just creating userspace libs in this lang). Anyways, since I'm probably most familiar with C++, I figured that STL <algorithm> might be a good starting point for ideas to attempt implementing. My data types are a bit restricted; no user-defined types really, and the only "sequences" or "containers" are essentially: 1) strings (can access individual characters as elements), and 2) vectors (random access, but every element is a basically Variant that can be any other type). There's no builtin concept of iterators; I could hack something together that imitates them using some functional tricks, but it doesn't really seem worth it. So I started implementing some common algorithm functions to just take first, last *indices* instead of *iterators* when operating on sequences. I also just recently started learning a bit about C++20 ranges, which seem much nicer than iterator based stuff, and I like the lazy evaluation aspect of them, so I'm wanting to incorporate some of those ideas. I've found cppreference.com very useful as a reference for <algorithm>, but its still very incomplete for <ranges>. So I guess my TL;DR question is: if there's any recommended reference to quickly get the gist of ranges from my weird standpoint, where I'm just sort copying ideas but not really using them directly in C++. Is just reading the official standard proposals my best bet? Also interested in any general discussion of perceived merits/flaws, and what people consider the most useful parts of <algorithm>, <ranges>, maybe a bit of <functional>(which I'm also not very familiar with), or other parts I should be looking at? Or is the overall idea of shoe-horning C++ stuff into this functional language terribly backwards and ill-advised?
|
# ? Dec 15, 2019 20:37 |
|
Hello friends. I am stumped in something that's probably silly.code:
If I declare the struct first, it tells me it doesn't know what this_method is. This is obviously a job for THIS. But I am working in embedded C and want to be careful and not do any monkey business. It's late, I'm super jetlagged and I am getting up to work soon. Any elegant/blindingly obvious suggestions? TIA
|
# ? Dec 15, 2019 21:13 |
|
Stick struct SoundStateKeeper; above the this_method typedef.
|
# ? Dec 15, 2019 21:24 |
|
Just writing struct SoundStateKeeper in the declaration is supposed to have that effect anyway. Do you have some weird warning on?
|
# ? Dec 15, 2019 23:44 |
|
Dawncloack posted:Hello friends. I am stumped in something that's probably silly. The scope of a struct name declared in a prototype is only that prototype .
|
# ? Dec 16, 2019 22:12 |
|
Oh, right, this is one of those rules that C just gets wrong (in the sense that it's not what people want or expect); C++ gets it right.
|
# ? Dec 17, 2019 01:17 |
|
peepsalot posted:So I guess my TL;DR question is: if there's any recommended reference to quickly get the gist of ranges from my weird standpoint, where I'm just sort copying ideas but not really using them directly in C++. You could try looking at the range-v3 library which, according to the website, is the basis for C++20 ranges.
|
# ? Dec 17, 2019 03:56 |
|
I'm looking for a recommended IDE or refactoring tool that could help me un-gently caress codebases that are using namespace std; that are neglected for a few years, and then now running into namespace collision with the stdlib. The quick and dirty is to rename things so they don't collide, but I think it would save future pain to get out of std namespace and be clear where things are coming from. Any suggestions?
|
# ? Jan 19, 2020 19:27 |
|
Does anyone have any idea how to use the imagemagick library to conveniently create an image from a 2D array or vector (Using a struct to hold RGB(A) data)? I'm flummoxed I've seen no documentation as to how its done and only one post on stackoverflow that doesn't work for me. This would at least be a little more convenient but the output is corrupt and unopenable Ideally just want a 2D array of rgba structs to feed into image magicks read function. There's a constructor with this signature documentation here: code:
code:
code:
So it'd be nice if being able to store RGB data in a struct worked, and then storing as a 2D array would be nice after that. But I'll settle for having a struct work fine. code:
|
# ? Jan 20, 2020 16:02 |
|
Raenir Salazar posted:This doesn't work for me at all, visual studio throws a syntax error with this. I think code:
code:
https://docs.microsoft.com/en-us/cpp/preprocessor/pack?redirectedfrom=MSDN&view=vs-2019 astr0man fucked around with this message at 17:44 on Jan 20, 2020 |
# ? Jan 20, 2020 17:41 |
|
astr0man posted:I think Thanks! I tried it but sadly that doesn't appear to resolve the issue of my png file being unopenable. code:
|
# ? Jan 20, 2020 17:55 |
|
Raenir Salazar posted:Thanks! I tried it but sadly that doesn't appear to resolve the issue of my png file being unopenable. I think what you want is in the "Low-Level Image Pixel Access" of the documentation you linked to. Blobs aren't the right way to go because they're supposed to already have encoding information (for PNG that would be a bunch of headers and metadata with the pixel depth, resolution, etc). It's giving you garbage because an RGB array is not a valid PNG file.
|
# ? Jan 20, 2020 22:37 |
|
I have a question: In my little 2D game, it basically has (simplified) C++ code:
My first thought is to add a flag that indicates when the vector is being iterated over, and modify startUpdatingObject() and stopUpdatingObject() so that if it's set they instead push the game object onto another vector (objectsToAdd and objectsToRemove, respectively), and then after iterating through objectsThatWantUpdates add/remove the contents of objectsToAdd/objectsToRemove from it. Another thought was a doubly linked list instead of a vector, but that seems like it'd be slower to iterate over. Doc Block fucked around with this message at 23:13 on Jan 24, 2020 |
# ? Jan 24, 2020 20:57 |
|
It is going to substantially simplify your life if there’s a hard rule that the game engine doesn’t hold any references to an object, and never calls update on it, after stopUpdatingObject is called. If you need to support reentrance here, I would suggest just iterating by index up to a stashed limit instead of the current size, making startUpdatingObject append to the end, and making stopUpdatingObject nil out entries instead of removing them when an update is in-flight. You can teach update to just remove nil entries when it sees them.
|
# ? Jan 25, 2020 01:41 |
|
I was going to suggest making a copy of the vector to iterate over, but it depends on what you want to happen if an unvisited element is removed, and if you want iteration to see elements added during iteration. And obviously if the vector is enormous then that might be too expensive, but it seems like it would be a lot simpler to reason about until you needed to optimize it further. If mutation during iteration is rare, you could lazily switch to a copy of the remainder of the vector when something first tries to add or remove. I did that in a language engine at one point, though the vectors in question were typically smaller than 50 elements, and mutation was a less than 1% case on our instrumented workloads.
|
# ? Jan 25, 2020 03:39 |
|
If the primary use case for objectsThatWantUpdates is to be iterated over while being modified std::list seems more appropriate than std::vector since std::list iterators are not invalidated by adds or removes (unless the element the iterator refers to is removed). This is no problem for adds, either put them on the front (if they are not to be acted on this loop) or the back (if they are to be acted on this loop). Removes are trickier because the current iterator could be removed. Instead of removing it immediately add the iterator to it to a list of zombies and flag a field in GameObject to mark it dead. In other spots, check the field before acting on it then at the end of the update loop remove the zombies from the main list.
|
# ? Jan 25, 2020 04:11 |
|
Doc Block posted:What's the best way to deal with this? To handle a std::vector potentially being modified multiple times, both adding and removing objects, while it's being iterated over? It might help to try and think of your state block in a very transactional way, i.e. while your game objects are updating, they don't actually make changes to any other objects, only query other objects for their current state. If you want to add a new object, create it and add it to a queue, but not the "real" list. If you want to delete an object, just set a flag on said object. At the end of the update loop, process the add queue, and delete any flagged objects. If you want to take this a step further, you can even decide that objects can't actually update themselves during the update loop, only decide what they want their update to be, and then process THAT afterwards, alongside the additions/deletions. One advantage of this approach is that you don't have state wobbling around while your objects are trying to decide what the world looks like and react to it appropriately. As an example of this sort of behavior, Box2D doesn't let you add/remove physics objects while it's resolving collisions, so if you want to, say, remove a wall because a meteor hit it, you have to remember that somehow and process it later after the physics step has resolved.
|
# ? Jan 25, 2020 04:14 |
|
rjmccall: the only time stopUpdatingObject will be called is when the object is being removed, and then no more references to it are stored. Totally agree that this makes things way simpler. Most game objects are static and don’t need to update every frame. It’s hard to imagine the objectsThatWantUpdates vector being larger than 30-50 elements. Iterating over the vector by index and nulling out removed objects instead of immediately removing them, then pruning null objects when seen is so simple I’m embarrassed I didn’t think of it already 👍 Subjunctive: I don’t want objects getting updates after they’ve been scheduled for removal, even if they haven’t been visited yet. Getting visited on the same frame they’re added is probably OK. Dren: I thought about using a linked list, but mostly objectsThatWantUpdates will just be iterated over. It’ll need to be modified during iteration sometimes, but at worst will still probably have triple digit frame counts between modifications. UraniumAnchor: the first part of your suggestion is similar to what I had first thought (a separate vector of objects to add/remove) but rjmccall's suggestion is simpler and what I've decided to go with. The second part of your suggestion seems a lot more robust, but it'll have to wait for the next game. Thanks everyone! Doc Block fucked around with this message at 09:20 on Jan 25, 2020 |
# ? Jan 25, 2020 04:35 |
|
I wrote a quick bench to verify that list takes longer to iterate than vector. I was a little surprised that it did, about twice as long. But I need to double check my bench to make sure it’s accurate.
|
# ? Jan 25, 2020 18:05 |
|
|
# ? Jun 7, 2024 06:50 |
|
Why would you need to verify that?
|
# ? Jan 25, 2020 18:17 |