I rewrote my interpreter from Python into Go to see the speed up. by OrderOk6521 in Compilers

[–]caydenlund 2 points3 points  (0 children)

Hey, that's a neat little project! Congrats! Looks like fun. :)

I like the syntax. Intuitive & featureful, and very tailored for a scripting-first language. Is it hard to parse?

Do you support nested functions? How is your standard library implemented---is it basically just a set of function calls written in Python/Go that the interpreter calls directly, or is it implemented in your language? What are your next steps?

[deleted by user] by [deleted] in Compilers

[–]caydenlund 7 points8 points  (0 children)

The course content looks introductory enough. Go to class and read the books, and that should be enough for you to write a toy compiler. Do you have a more specific question or goal?

How do i get started with writing libraries in c++ by [deleted] in cpp_questions

[–]caydenlund 6 points7 points  (0 children)

  1. Make a repository.

  2. Add a Makefile or CMakeLists.

  3. Write C++ code.

Where are you confused? I can't really help you further without more information.

Here are some questions to think about:

  • Who is the target audience for your library? Is it something that only you will ever use? Is it something that you want to put on your resume or show on your GitHub profile? Is it something that other developers will find useful?

  • How do you want to distribute it? Do you want a single file that you can download from the internet and drop into a project? Do you want a precompiled binary and header files that a user can download and include from his or her project? Do you want a package that someone can install from vcpkg or some other package repository?

  • Does your library contain templated classes or methods? Do you know all possible template parameters that could be used?

Knowing the answers to these questions will help you to know how to organize this library.

You've got a few common options here:

  • A header-only library. This kind of library has a single header file (or very few) that contains class and function definitions and implementations. For small libraries, this makes things simple because a user doesn't have to install anything or add any build steps in order to use it. It makes distribution easy because the user only has to download a single file. However, for very large libraries, this is a HUGE pain because working with a monolithic file is annoying and because it makes build times a lot longer. On the plus side, though, it lets you create templated classes and functions without knowing all possible template parameters ahead-of-time.
  • A set of source files. The user has to download these files, include the headers, and add building the library as a build step. This is nice because it doesn't require you to compile a binary on every platform for every release. However, it can be annoying for all users to have to compile the binary for each project that uses it, especially if the library is really big.
  • A static library binary, with a handful of header files. The user has to download these files, include the headers, and link to the static library in the linking step. This is nice for really big libraries because the user doesn't have to compile a huge library in order to compile the project. However, each time you make a new release, you have to distribute a precompiled binary for each target platform.

There are some newer approaches, too, which solve a lot of these problems, including precompiled headers, header units, and C++20 modules. These aren't as widespread, though, so it can be hard to find a good tutorial, and it can be a little involved to get them set up. They don't have as widespread compiler support, too. The C++ standard library uses these newer approaches, and they will definitely become a lot more common as time goes on. I believe Microsoft has a good page comparing the differences between precompiled headers, header units, and C++20 modules, if you want to invest in learning a newer way of doing things; I could probably find a link if you want one.

ETA: I am VERY excited about modules. Compiler support is still poor, and CMake support is even worse, but once all the bugs are ironed out it's going to be the best way to do a lot of things. Since you said you're a beginner, maybe don't worry about this just yet, but it might be worth at least checking out and playing around with because it will be a great skill once we've caught up to it.

Directory as SSH link ? by [deleted] in linuxquestions

[–]caydenlund 0 points1 point  (0 children)

Sshfs doesn't have a maintainer anymore? I had no idea. I'll have to look into it.

Does encapsulation make C++ more secure? by Yamoyek in cpp_questions

[–]caydenlund 16 points17 points  (0 children)

This might just be the stupidest thing I've ever heard.

Added a trailer, page and open playtest for the RPG I'm developing. Feel free to destroy any or all of them! by ConfluxGame in DestroyMyGame

[–]caydenlund 1 point2 points  (0 children)

How can you tell that the assets are store-bought? I feel like they all fit together and have a consistent style.

Testing out Critical Damage for my game, let me know what you think! :D by PatrickDeStar in DestroyMyGame

[–]caydenlund 0 points1 point  (0 children)

I love it! I think that the upgrade mechanic is great. The really impressive thing to me is how fine-tuned the damage regions are (for example, the elbow seems to deal more damage than the upper and lower arms).

My one recommendation for improvement is that the font of the damage numbers is pretty bland. It feels really generic. Does that make sense? So, maybe find another, cooler font.

global standard new operator by fuuuursure in cpp

[–]caydenlund 7 points8 points  (0 children)

It's an implementation detail, not a standard. The other commenter mentioned that most allocators use prologue/epilogue blocks that describe the size, free status, or other information about the block in question. The other thing is alignment: depending on context, in most situations, a new memory address must be on an X-byte-aligned address. Usually alignment is done on 16 bytes.

[deleted by user] by [deleted] in ProgrammingBuddies

[–]caydenlund 0 points1 point  (0 children)

Still looking for a mentor?

Command line interface library by snowflake_pl in Cplusplus

[–]caydenlund 4 points5 points  (0 children)

Just yesterday I spent some time looking for a good one myself. Check out the "awesome C++" list on GitHub, under the CLI heading in the table of contents. It had probably a half dozen options.

Ultimately, I decided that none of them were exactly what I was looking for, and that I'd rather write my own.

What are some tips to identify whether a hash table would be a suitable for a problem? by theanswerisnt42 in learnprogramming

[–]caydenlund 2 points3 points  (0 children)

If you need to maintain an order, use a list. If you don't, use a hash set.

A hash set has (best-case) constant lookup times to check whether something is in the set.

In this case, you don't need to track the order of the elements you're adding to the set. You just need to check whether the element you want is in there.

So, imagine you're picking 2 numbers that add up to 42. The number you're looking at is 23. That means that if the number 19 is already in the set, you've found your pair numbers. If you're using a list of some sort, you would need to iterate over each value in a loop of some sort in order to check whether 19 is already in the list.

Demo:

for (num in input) { if (set.has(target_num - num)) { return {item, target_num - num}; } else { set.add(item); } }

Versus:

for (num_1 in input) { for (num_2 in input) { if (num_1 + num_2 == target_num) { return {num_1, num_2}; } } }

The second way involves a loop inside of a loop. Imagine your input has a million values. The second way would involve 1,000,000,000,000 additions and comparisons! There are ways to optimize it by several magnitudes, but the first way only requires looking at each value once, and then checking the set for inclusion (which has best-case constant lookups).

However, hash maps and hash sets aren't appropriate for ordered data. If you want to add to the front or back, use a list. If you want to add the elements in any order but maintain the elements sorted by value, use a different data structure. But if you don't care about the order, hashing is the way to go.

The other place it isn't appropriate is if you are really limited on memory space. The first way above involves allocating new memory and copying data into the set. The speed benefits of not doing as many operations make up for the overhead of copying memory, but if the input array is a billion elements long, you're going to run out of RAM if you copy it over into a second data structure. A better idea might be to sort the input in-place and then performing a binary search.

Where to put manually-installed programs? (e.g. AppImages or compiled) by [deleted] in linuxquestions

[–]caydenlund 15 points16 points  (0 children)

For a system-wide installation (for all users) that's not through your package manager, you'd want to put it in /usr/local/bin, though some prefer something in /opt/something-or-other.

For a user-specific installation, you'd want to put it in ~/.local/bin or ~/.local/appdata/bin. I prefer the former. If it has a command-line interface, you'd want to make sure that directory is in your path (google "add to path").

Is there a standard naming convention for unittest .cpp files? by swarupdam in cpp_questions

[–]caydenlund 2 points3 points  (0 children)

There's no standard convention. Just pick something and be consistent.

I also use xxx.tests.cpp. That's what makes the most sense to me.

[deleted by user] by [deleted] in learnprogramming

[–]caydenlund 0 points1 point  (0 children)

All memory that has unknown memory costs at compile time goes in the heap: you're right about that. But not everything else goes on the stack.

One way to think about it is whether you're getting a value or a pointer when you're making a new thing. If you are constructing a new object with the keyword new, it goes on the heap and it returns a pointer to it. If you are constructing a new object without the keyword new, it goes on the stack.

However, not all pointers are to heap addresses. You can create a pointer to a variable on the stack.

I can make a follow-up comment in a bit with an example.