• Advertisement

Bregma

GDNet+ Basic
  • Content count

    3010
  • Joined

  • Last visited

  1. QFE. Formatting a format string is a bad bad thing to do. If you include any user input at all, you're opening a gaping hole (imagine a username of "%s"). It's as if you've said to yourself "how can I take one of the most insecure, error-prone, dangerous parts of the language and make it more error-prone, dangerous, and insecure?" Then, of course you come here asking "I've made the most error-prone part of the language more error-prone and now I have an error, can I keep digging until I find my way out?" Modifying format strings that get used elsewhere at some unknown time is implicitly modifying global state as a side-effect of your functions. Instead, make your functions pure and have them returns already-formatted strings, only assembling them into larger strings when you have control and not as a global variable.
  2. On the other hand, if your tool fails to do what you need, you shouldn't adjust yourself to your tool's limitations. You should get a better tool. There are many alternatives to Visual Studio available. Try Microsoft's VS Code for example.
  3. (1) Why are you copying to a temporary buffer and then leaking it? (2) Have you double-checked what GetText() returns (eg. using a debugger)?
  4. Passing a C++ object through C '...' (varargs) is completely undefined behaviour. Avoid undefined behaviour, you never know what you're going to get. Follow Kylotan's advice.
  5. The name resolution rules in C++ are sensible and if they weren't the way they are it would cause many many more problems than one obscure corner case caused by unfortunate variable name selection. What is the restriction on namespaces in your struct that you aren't allowed to use the fully qualified name of a variable to fully qualify its name? Logically, you want the variable at namespace scope, so saying you're not allowed by the logic do do the logic seems mysterious to me. It doesn't sound like the design fault is in the language to me.
  6. One catch is that a number of popular user environments tie operating system evens to the windowing system, and for a very good reason (a multi-tasking OS requires user focus to know the target of many kinds of events, like input, and focus is dependent on the windowing system).
  7. C++ need more randomization

    Store a random generator and use a uniform distribution object to provide your values. It only takes the storage space of one additional integer. Two extra lines of code.
  8. Problems with starting out on linux

    Considering it was first released in 2015, quite some time I would guess. We had a serious effort at Canonical before that helping her to get it to work well. Ironically, the people who did a lot of that work are now working at Epic making the Unreal engine work better on Linux. It's a small and specialized developer pool. You might also consider evaluating the worthy Godot.
  9. std::make_shared vs. new

    You seem a little confused by what a weak_ptr is and how it relates to a shared_ptr?
  10. C++ Invalid read of size 8

    If you don't allocate memory for the pvtElements member, you're going to get an "invalid read" error when you try to read from that memory.
  11. Coding moods

    Full-time programmers probably spend more of their time in meetings, clicking on online time trackers and bug trackers, moving cards around on kanban boards, "researching" on the web, and doing code reviews than they do actual writing code.
  12. Is there a doctor in the house?

    Just a point of order, but "obsession" refers to repetitive thoughts. The term "compulsion" refers to repetitive actions. So, it would be Button Pressing Compulsion Disorder (BPCD) if anything. Doesn't play as nicely as an acronym but could still get you sympathy at parties ("My wife was diagnosed with BPCD and she keeps pushing for a cure...").
  13. initialize std::thread

    Unless of course the compiler decides to reorder the instructions in your code, or the CPU is superscalar and performs out-of-order and/or speculative execution, and you end up using the results of your interlocked add before actually calling that instruction: a locked processor instruction does not affect that but a fence does. Then again, you're using this in a multi-threaded application, so you're going to get pre-empted right after your InterlockAdd and the value gets changed by the other thread after you've obtained it, and you're left scratching your head why things don't work, sometimes, maybe.
  14. sys/socket.h and std::thread (C__)

    listen() is a system call: it will block the thread briefly while it switches to the kernel and performs some setup operations. It gets called once (per server socket, so generally once per application) during startup, and is fairly resource-lean and fast. You call accept() to wait for connection attempts on a socket that you have previously called listen() on. The accept() call is also a system call (requires a switch to kernel mode to perform its operations, which means it steps out of the ready-thread queue and go on the IO-wait queue), and whether it performs a blocking wait on the socket or not depends on if the socket is in blocking mode or not.
  15. sys/socket.h and std::thread (C__)

    Well, yes, you could use blocking sockets and have a thread listen on the socket, accepting client connections as they come, and go back to blocking on the accept call. That's all it would do. It's a very sensible way to program sockets and easy to reason about. You could also use non-blocking sockets and use a multiplexor like select/poll/epoll/kqueue to combine all of your socket waits onto a single thread, and dispatch them via callbacks to a worker thread pool. Again, not too difficult to reason about, but targeted towards a POSIX I/O model rather than a Windows I/O model. If you're using an Windows-based system, you could use IOCP and overlapped I/O to handle everything, including dispatching commands to a thread queue if you really want.
  • Advertisement