• Hey, guest user. Hope you're enjoying NeoGAF! Have you considered registering for an account? Come join us and add your take to the daily discourse.

Programming |OT| C is better than C++! No, C++ is better than C

Obviously it also a ton if you have a connection to skip the front door interviews.

Doesn't matter how many connections you have, you're not skipping the *real* interview, which is by far the hardest part. Connections might make it easier for you to get a call back from HR, but it means absolutely zero when it comes to passing the interview. And even then, if you don't get a call back from HR, you probably weren't going to pass the interview anyway (i.e. HR is overly liberal in who they call back, so there are very few false negatives at that early of a stage)
 
Doesn't matter how many connections you have, you're not skipping the *real* interview, which is by far the hardest part. Connections might make it easier for you to get a call back from HR, but it means absolutely zero when it comes to passing the interview. And even then, if you don't get a call back from HR, you probably weren't going to pass the interview anyway (i.e. HR is overly liberal in who they call back, so there are very few false negatives at that early of a stage)
The screening interview is harder than the "real" interview for a certain type of engineer. Has to do with the sort of questions they ask (I assume you've taken it? Study up on your combinatorics, even if you haven't used it since college you might be expected to know it!)

But yes, you need to pass the real interview regardless. Well, if you're a wizard maybe they don't even bother, but odds are you are not a wizard.
 
The screening interview is harder than the "real" interview for a certain type of engineer. Has to do with the sort of questions they ask (I assume you've taken it? Study up on your combinatorics, even if you haven't used it since college you might be expected to know it!)

But yes, you need to pass the real interview regardless. Well, if you're a wizard maybe they don't even bother, but odds are you are not a wizard.

The thing is, everyone asks something different, and every interviewer has a different amount of experience interviewing, and a different amount of experience with the question they're asking (having experience asking a question is surprisingly important for questions of that caliber)

Phone screen questions tend to be softballs, but there's always the chance you get the interviewer who's never phone screened before, chose a bad question, or it just happens to be your anti question (ie every person -- no matter how good -- has one subject they will bomb if asked about)

I don't know of anyone ever having skipped the interview, so I'm going to say it's either not possible or you have to have be world renowned in a particular subject area
 
The thing is, everyone asks something different, and every interviewer has a different amount of experience interviewing, and a different amount of experience with the question they're asking (having experience asking a question is surprisingly important for questions of that caliber)

Phone screen questions tend to be softballs, but there's always the chance you get the interviewer who's never phone screened before, chose a bad question, or it just happens to be your anti question (ie every person -- no matter how good -- has one subject they will bomb if asked about)

I don't know of anyone ever having skipped the interview, so I'm going to say it's either not possible or you have to have be world renowned in a particular subject area
Agreed. What I'm getting at with the screening interview is that you have a non-zero chance of bombing it, so your chances of landing the job will obviously be (slightly) better if you get to skip it.

The bolded is what I meant by "wizard". Though there's also their acqui-hire process -- I don't know what that looks like.
 
Agreed. What I'm getting at with the screening interview is that you have a non-zero chance of bombing it, so your chances of landing the job will obviously be (slightly) better if you get to skip it.
True you have a non zero chance of bombing it, but i think the conditional probability of passing the onsite given you've bombed the phone screen is very close to 0. That's literally the intent of the phone screen, to save them from wasting 5 engineers' time on someone who isn't going to pass anyway. I agree it's probably not exactly 0, but I don't think its significant

Edit: That said, I've never heard of anyone skipping the phone screen either. It only takes 45 minutes, so it's not a big deal
 

BakedYams

Slayer of Combofiends
As long as the interviewers are relaxed and have know how to progress a conversation, its awesome. If they're kinda geeky/nerdy than even better, just talk about code all day lol

I agree it can be dauting the first time you do it, but honestly it's not that hard. And you're going to have to do this no matter if you're using Visual Studio, Makefiles, CMake, or anything else. The reason is that your program and the unit test runner are two separate executables that need to share the same code -- the code that is being tested.

The way you share code in this way is by creating libraries.

To get up and running the quickest, you can literally change your entire project to a static library. Right click the project node, choose Properties, click General, and set Configuration Type to Static Library (.lib). Change your main function to be called something else like RunProgram(), make a header file and declare RunProgram() in the header file. I'll just call this header file foo.h, but make it something more appropriate.

Now create a new project, this time an Application (.exe). But do it by right clicking the root node in Solution Explorer and choosing Add -> New Project. When VS finishes creating it, you'll now have two projects in the same solution. In your new application project, add a #include "foo.h", then in main() simply call RunProgram().

To make it automatically link the library into the application, right click the project node of the application, choose Build Dependencies -> Project Dependencies, and then click the checkbox for the library. You'll probably need to set the include directories in your exe project to find the folder where the include files for the library are. This is in Project Properties -> C/C++ -> General -> Additional Include Directories.

In a production environment, you would probably create a more realistic separation between your driver / application and your core functionality that you're testing, instead of simply having your main() function be one line that calls the static library. For example, command line parsing, user input, etc would all be handled in the application while processing and utility libraries etc would be handled in the library.

In any case, when you've got all this working, creating the unit test suite is not much different than the application. Make a new Application, add a dependency, go to the Linker and Include settings and add the appropriate paths for gtest, then #include files from your library and start using them in yoru tests.

One common solution for handling the situation with include file paths is for a project to do something like this:

Code:
project
|__ project.sln
|__ src
    |__ application
        |__ main.cpp
        |__ application.vcxproj
    |__ library1
        |__ lib1.cpp
        |__ lib1.vcxproj
    |__ library2
        |__ lib2.cpp
        |__ lib2.vcxproj
|__ include
    |__ application
    |__ library1
        |__ lib1.h
    |__ library2
        |__ lib2.h

Now, in every project, you set your Additional Include folders to $(SolutionDir)include. Then in your application.cpp, you can simply write something like this:

#include "library1/lib1.h"
#include "library2/lib2.h"

And it will automatically find it. This way you dont' have to go manually screw around with the include path settings for every single project. It's always exactly the same value for every project, just "$(SolutionDir)include".

Anyway this is a lot to take in the first time you do it, but it's fairly intuitive once you get used to it.

Oh god.... gulp. I'm using sublime note 2, would I just be able to use #include and the name of the library or would I have to do a separate file named "foo.cpp" and change my main function to RunProgram() and then include that file into my new project and call RunProgram() in that main function? Where would the library be coded in if I were to do the later? I'm a complete novice when it comes to this so I just wanna learn how to do this.
 

Rur0ni

Member
Getting hired at Google is 100% how well you do on the interview. Which itself is about 60% luck.
It's pretty interesting. You can get an odd panel lineup and get roasted, and an engineer who isn't as talented overall ends up skating through. Combination of the right questions, right interviewers.

Hey, it has a mocking framework included so that's a huge plus! Chrome + LLVM + cpp_is_king is enough endorsement for me.
+1

I use gtest as well.
 
As long as the interviewers are relaxed and have know how to progress a conversation, its awesome. If they're kinda geeky/nerdy than even better, just talk about code all day lol



Oh god.... gulp. I'm using sublime note 2, would I just be able to use #include and the name of the library or would I have to do a separate file named "foo.cpp" and change my main function to RunProgram() and then include that file into my new project and call RunProgram() in that main function? Where would the library be coded in if I were to do the later? I'm a complete novice when it comes to this so I just wanna learn how to do this.

Since you weren't the original person who asked the question, I'm not sure if you're using the same environment as him. Are you using Visual Studio or something else?

Also if you just want to make a simple program, you don't have to do this. I was just explaining how to set up a project that facilitates sharing code across multiple applications. In this case it's for the purpose of unit testing, but it applies in pretty much any large-scale project as well.
 
So I'm really bad at... user-proofing(?) my programs at this point. Does anyone have any pointers? For example, in this Vigenere cipher I was working on, what would be the best ways to make sure users don't enter in things? Especially through the command line?

Code:
#include <stdio.h>
#include <cs50.h> 
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
int main(int argc, string argv[]) {
    //Set key to command line value
    string key = argv[1];
    
    //Prompt user for text to be encrypted
    printf("Enter text to be encrypted: ");
    string input = GetString();
    string output = input;
    
    for(int i = 0, n = strlen(input); i < n; i++) {
        int vKey = (key[i % strlen(key)]-96);
        if(isalpha(input[i])) {
            output[i] = input[i] + (vKey % 26);
            if (!isalpha(output[i])) {
                output[i] -= 26;
            }    
        } 
    } 
    printf("The output is %s\n", output);
}
 

Makai

Member
So I'm really bad at... user-proofing(?) my programs at this point. Does anyone have any pointers? For example, in this Vigenere cipher I was working on, what would be the best ways to make sure users don't enter in things? Especially through the command line?

You could make a unit test that exhaustively tests all cases to be sure. Or at least some subset of them since that would take a while for this problem.
 

upandaway

Member
So I'm really bad at... user-proofing(?) my programs at this point. Does anyone have any pointers? For example, in this Vigenere cipher I was working on, what would be the best ways to make sure users don't enter in things? Especially through the command line?
I think that's one of the things TDD is supposed to help with. Even if you don't do TDD, just documenting the edge cases before writing the code itself would go a long way (in making you better at identifying them, but also in making the code less breakable)
 

Koren

Member
So I'm really bad at... user-proofing(?) my programs at this point. Does anyone have any pointers? For example, in this Vigenere cipher I was working on, what would be the best ways to make sure users don't enter in things? Especially through the command line?
I usually try to imagine things that could make each line go bad...

There's a couple things in your code that can trigger some questions.

Code:
string key = argv[1];
For each table, you can think about what you would need to go outside of the borders. There, are you sure that there is 2 elements in argv? What appends if the user doesn't provide an argument in the command line? You'd better exit the program early (with a help message) if argc ==0...

Code:
string input = GetString();
A careful read of functions you use are helpful...

The interesting part of GetString in CS50 is the edge case:
Code:
Returns NULL upon error or no input whatsoever (i.e., just EOF).
So, what appends if the user managed to send an EOF or fill memory? You should check each edge case before trying to do anything with the result of the function, assuming everything went correctly.

After that, you want to check the types...
Code:
strlen(input)
input is a string. strlen ask for a const char*. Thus, you have a cast happening here. Is it safe?

Also, is there a better way to get the length, using the string methods? (strlen is usually for c-style strings)

Code:
int vKey = (key[i % strlen(key)]-96);
There, you cast a char into an integer, same question... What happen if the user hasn't provided lowercase chars as its program argument? Would a negative value vor vKey be an issue?

(btw, computing the length of key each time is not the best idea, although not a bug)

Code:
isalpha(input[i])
isalpha ask for an int, so once again a cast...

Besides, isalpha is locale-dependant if I'm not mistaken. Can the user set the locale (maliciously or not) so that your program will give incorrect result or worse?

Also, the part
Code:
            output[i] = input[i] + (vKey % 26);
            if (!isalpha(output[i])) {
                output[i] -= 26;
            }
still casts a lot, and make assumptions on how which locale/character encoding is.

The locale could give you strange results (in some locales, accented characters for example gives True for isalpha, so you'll encode them in a very strange way... I even think that if the input is in UTF-8, and the locale specify something else, you could get an invalid string as the output).

Beside that, assuming a locale where isalpha = 'A-Z'+'a-z', I think you should be safe with most encodings, like UTF-8 or UTF-16, since it won't try to change anything that doesn't begin with a 0. Remember that strings don't manipulate actual characters, though, but chars, which are single-bytes. It would still produce REALLY strange results with some encodings (like ISO-2022, although I really double you'll encounter this, since it would encode the escape sequences).


At the end of the day, string management in C is a nightmare, and in C++, it's barely better thanks to "string", but still far from an easy task... If I had received a penny each time I've read "UTF-8 is complex with a variable number of bytes for each char, you should use UTF-16 so that each character is 16-bits"... (hint: it's not)


For all this reasons, I wouldn't touch isalpha with a mile-long pole myself.
 

BakedYams

Slayer of Combofiends
Since you weren't the original person who asked the question, I'm not sure if you're using the same environment as him. Are you using Visual Studio or something else?

Also if you just want to make a simple program, you don't have to do this. I was just explaining how to set up a project that facilitates sharing code across multiple applications. In this case it's for the purpose of unit testing, but it applies in pretty much any large-scale project as well.

I'm just using sublime with MinGW as my compiler. If I were to ever release an .exe for people to try out, I'm worried that they would need a specific library that makes cout work in C++. The name of the library is libstdc++-6.dll

For my .exe's to work, I need to include this file in my folder and I want to know if just using #include libstdc++-6.dll will work without it being in the folder.

South Italy. Great sea,but not much going on in terms of tech :p
I did check on meetup.com but the only events I found are from a certain polical movement lol.

Well that's the middle of nowhere in regards to tech lol, forums are your best bet and if you want to pursue a career in tech (im a novice so take my advice lightly) you can always move to where the tech is.
 

Koren

Member
I'm just using sublime with MinGW as my compiler. If I were to ever release an .exe for people to try out, I'm worried that they would need a specific library that makes cout work in C++. The name of the library is libstdc++-6.dll

For my .exe's to work, I need to include this file in my folder and I want to know if just using #include libstdc++-6.dll will work without it being in the folder.
If I understand your question correctly*, it only needs to be somewhere in the path, but also that the version is compatible, which is sometimes tricky (although I'm not sure it's the case with libstdc++) You can also get into problems when people try to double-click on the executable and the working directory is not the one where you put the dll, if you decide to distribute the program with it.


* not sure I am because of the #include... You don't want to put a #include of a dll inside the source file? Because it would be a totally wrong idea...

That being said, I'd suggest you to get rid of the dependency by statically linking the library when you build your executable.

If I'm not mistaken, the option required is -static-libstdc++

I'd also suggest -static-libgcc
 
I'm not quite sure I understand how to work with dynamic arrays.

Lets say I have

int* GAF;

then I initialize GAF with new int[5], and then later set the values of the array to 1, 2, 3, 4, and 5.

So now we have the dynamic array {1, 2, 3, 4, 5}.

Now lets say my program later needs to add an element to the array. Well the array is already full. So now I want to make a larger array. But I still want it to be dynamic, and I want GAF to point to this new array rather than the old one. Is this how I would accomplish it?

Code:
int* temp1 = new int[6]; //make the new dynamic array
int* temp2 = GAF; //make a new pointer to point at the array GAF points to.
GAF = temp1; //GAF now points to the new array
delete [] temp2; //deallocate the old array
temp2 = 0

Basically what I want to do is create a new larger dynamic array, have GAF point to that new array, and then deallocate the older smaller array.
 
I'm not quite sure I understand how to work with dynamic arrays.

Lets say I have

int* GAF;

then I initialize GAF with new int[5], and then later set the values of the array to 1, 2, 3, 4, and 5.

So now we have the dynamic array {1, 2, 3, 4, 5}.

Now lets say my program later needs to add an element to the array. Well the array is already full. So now I want to make a larger array. But I still want it to be dynamic, and I want GAF to point to this new array rather than the old one. Is this how I would accomplish it?

Code:
int* temp1 = new int[6]; //make the new dynamic array
int* temp2 = GAF; //make a new pointer to point at the array GAF points to.
GAF = temp1; //GAF now points to the new array
delete [] temp2; //deallocate the old array
temp2 = 0

Basically what I want to do is create a new larger dynamic array, have GAF point to that new array, and then deallocate the older smaller array.
You don't need two temporary pointers for that, just one. The idea is:
1. Allocate the new array.
2. Copy over all the contents of the old array into the new one.
3. Delete the old array.
4. Make the old array pointer point to the new array.

You've done step 1, 3 and 4, (although not in that order, which meant you're using an extra, unnecessary pointer). You're missing step 2.
 
You don't need two temporary pointers for that, just one. The idea is:
1. Allocate the new array.
2. Copy over all the contents of the old array into the new one.
3. Delete the old array.
4. Make the old array pointer point to the new array.

You've done step 1, 3 and 4, (although not in that order, which meant you're using an extra, unnecessary pointer). You're missing step 2.

Yeah I left out step 2 on purpose here.

But if I were to include it and use only 1 temporary pointer:

Code:
int* GAF; (lets say GAF is dynamic array {1, 2, 3, 4, 5}
int* temp1 = new int[6];

for (i = 0; i < 5; i++)
{
temp1[i] = GAF[i]; //copy over old values into temp1
}

delete [] GAF //dallocate old array
GAF = temp1

And that should work.

Question: Lets say this were a function instead. GAF is a global variable. But temp1 is a local variable created by the function for copying over values. When I set GAF = temp1 in that function, and then the function exits... does that cause problems? Or will it be ok because it is a dynamic array and the memory is in the heap not the stack?
 
Question: Lets say this were a function instead. GAF is a global variable. But temp1 is a local variable created by the function for copying over values. When I set GAF = temp1 in that function, and then the function exits... does that cause problems? Or will it be ok because it is a dynamic array and the memory is in the heap not the stack?
Correct. Memory allocated on the heap has to be freed manually. The temp1 variable will go out of scope once the function is over, but that's only the pointer. The memory it points to won't be freed. This is why you have to be careful with dynamically allocated memory. Removing the pointer doesn't actually free the memory. So if the pointer disappears, the memory is still allocated, but you have no pointer to it so you can't free it or use it and you get a memory leak.

Code:
void memoryLeak() {
    int* terribleness = new int[64];
}

If you make it a function, setting what GAF points to won't actually change the original pointer, though. So you'll have to use a pointer to a pointer (int**). (If you're passing it as an argument to the function, you shouldn't use global variables.)
 
Why is this the case?
Unless you're using references, arguments are passed by value. Even pointer arguments. It's just that when using a pointer, the value you're passing is the value of the pointer, i.e. the memory adress.

So when you have your array GAF defined as:
Code:
int* GAF = new int[5];
what does GAF actually contain? It contains the memory adress to the first element in the array.

If we do:
Code:
int* GAF2 = GAF;
GAF2 = 10;
Does GAF change? No, GAF2 pointed to the same memory as GAF for a while, but it's not the same variable. Changing GAF2 doesn't affect GAF (but since they're pointing to the same memory, changing the memory that GAF2 points to will change the memory that GAF points to).

So when we call a function, we create a new variable that contains the same value as GAF (it points to the same memory) but it's not the same variable.

Let's say we have a function that takes:
Code:
void replaceArray(int* array) {
    delete[] array;
    array = new int[6];
}
and we're calling it using
Code:
replaceArray(GAF);

We're freeing the old array and replacing it with a new one. Or at least that's what we think we're doing. Here's what's actually happening:
Code:
int* array = GAF;
delete[] array;
array = new int[6];
array points to the same memory as GAF but it's not the same variable. So when we set what array points to, GAF isn't changed. We're actually causing two serious problems here. We lose array, and so we no longer have a pointer to the memory we just created. We've created a memory leak. Furthermore, we freed the memory that GAF pointed to, but it's still pointing to that memory. If we try to use GAF now, we'll try to use memory that has already been freed. That's no good.

In order to actually change GAF (not the memory it points to but the variable itself) we need a pointer to it. GAF is already a pointer, so it'll be a pointer to a pointer, or int**. We can have a pointer to a pointer to a pointer, in how many steps we want (but at that point it's pretty confusing, the most you'll probably ever deal with is a **).


If it's a method and you're changing a member variable, it'll work. Or if it's a global variable (but global variables ar fugly). Or you'll have to use a pointer-pointer.
 

JeTmAn81

Member
Regarding dynamic arrays, if you're in C++ don't you really want to use vectors for that purpose since a vector is basically an automatically resizing array?

Otherwise if you're just using regular arrays and you anticipate a variable number of resizes to your array, you may want to resize in a way that avoids thrashing:

Thrashing is a pathological phenomena that could happen as the underlying array resizes at threshold X. If an element is added at X+1, the underlying array is enlarged. If an element is removed leaving X-1, the underlying array is shrunk.

"If a client calls push, pop, push, pop then it's going to be doubling, halving, doubling, halving creating arrays on every operation taking time proportional to N on every operation and therefore quadratic time for everything. The efficient solution is to wait for the array to get one quarter full before you halve it... There won't be another resizing operation until it gets totally full or half again full. So the invariant of that is that the array is always between 25% or 100% full and that every time time you resize you've already paid for it in an amortised sense."

http://javaagile.blogspot.com/2013/02/thrashing-and-amortization.html
 

BakedYams

Slayer of Combofiends
If I understand your question correctly*, it only needs to be somewhere in the path, but also that the version is compatible, which is sometimes tricky (although I'm not sure it's the case with libstdc++) You can also get into problems when people try to double-click on the executable and the working directory is not the one where you put the dll, if you decide to distribute the program with it.


* not sure I am because of the #include... You don't want to put a #include of a dll inside the source file? Because it would be a totally wrong idea...

That being said, I'd suggest you to get rid of the dependency by statically linking the library when you build your executable.

If I'm not mistaken, the option required is -static-libstdc++

I'd also suggest -static-libgcc

Would I write that in code or type that in the command prompt beforehand? I read the same thing on a forum and didn't quite understand where I needed to do this.

Regarding dynamic arrays, if you're in C++ don't you really want to use vectors for that purpose since a vector is basically an automatically resizing array?

Otherwise if you're just using regular arrays and you anticipate a variable number of resizes to your array, you may want to resize in a way that avoids thrashing:

http://javaagile.blogspot.com/2013/02/thrashing-and-amortization.html

Jetman, take me in as your pupil.
 
Hey GAF, I've been kind of stumped on an assignment here for a while and was wondering if anyone could lend a hand (1st year university assignment using python 3 and pygame).

I'm making a memory game type program where you have to match hidden images together. If the two images you select do not match they are supposed to become hidden again. If they do match they are supposed to remain revealed. The assignment is our first opportunity to learn and use classes in python. So the images are stored in my "Tile" class and then I have a "Board" class that contains 4 rows and columns of the tiles.

I'm currently struggling with matching the two images. We were given two hints on how to do this:
  • use is or is not operators to determine whether tiles are identical
  • implement a == operator using a method name _equal_, a rich comparison method. To implement the __equal__ method in the tile class, you should return false if self or the other tile is the None object. If neither is the None object you can check to see if the images in the tiles are == to each other, returning True if the images are equal and False if the images are not equal

I don't really understand what rich comparison method is, despite looking it up. I could really use some help or just general direction to figure this out this matching problem. Thanks in advance GAF!
 

Makai

Member
Is there a dumbed down explanation I could read for why Python does not really have pointers like C++ does?
Languages have evolved since the 1980s. Most modern languages use references instead of pointers. It's basically doing the work for you - improving your productivity and eliminating the possibility of a class of bugs.
 
Is there a dumbed down explanation I could read for why Python does not really have pointers like C++ does?

It's a design tradeoff. A language like C++ is designed intentionally to be close to the metal and gives the programmer explicit control over memory management.

A language like Python is intentionally designed to remove this aspect of control from the programmer and allow the user to focus on higher order language constructs, rapid prototyping, reflection, etc.

Pointers are an inherently unsafe construct, because they map directly to the physical machine. By making it impossible to directly manipulate bytes of memory, you also decrease the attack surface from a security perspective, so it makes programs harder to exploit.

Languages have evolved since the 1980s. Most modern languages use references instead of pointers. It's basically doing the work for you - improving your productivity and eliminating the possibility of a class of bugs.

"Evolution" sounds synonymous with "supeior". Garbage collection is not superior to explicit memory management. It serves a different need, and while it might be superior in some aspects, it is inferior in others.
 

JeTmAn81

Member
Jetman, take me in as your pupil.

Sorry, too much impostor syndrome here. I didn't even know what a vector was until I looked it up this week. cpp_is_king seems to be the guru around these parts, maybe you can be his padawan.

"Evolution" sounds synonymous with "supeior". Garbage collection is not superior to explicit memory management. It serves a different need, and while it might be superior in some aspects, it is inferior in others.

Yeah, it's more that programming needs have expanded to the point where the overhead of system-managed memory is acceptable for many scenarios. But obviously even today you don't want that overhead if you're doing something that requires as little memory use and processing time as possible like embedded systems.
 
I'm just using sublime with MinGW as my compiler. If I were to ever release an .exe for people to try out, I'm worried that they would need a specific library that makes cout work in C++. The name of the library is libstdc++-6.dll

For my .exe's to work, I need to include this file in my folder and I want to know if just using #include libstdc++-6.dll will work without it being in the folder.

I know next to nothing about using MinGW toolchain. If you're using MSVC, then the way it works is that you have 2 options how to link against the standard libraries (C Runtime Library and C++ Standard Library). statically or dynamically. If you use static linking, then when you build your program it looks for a .lib file or a .a file, and literally embeds the libraries into your exe. You could ship your exe to anyone, even someone with the wrong version of the library installed on their system, and your program would still work because the correct version of the library is already embedded int he executable.

If you use dynamic linking, it requires the user to have the libraries installed on the system. When you run the exe, it will look for a .dll file on the system and load that at runtime. Ever installed a game and it says you need to install DirectX? Or if you're old enough to remember back in the day when you would install something and it said you needed to install MSVCRT10.DLL? That's dynamic linking. If it can't find the right version of a library, your program doesn't work.

From this explanation it probably sounds like static linking is the way to go, but I would strongly advise using dynamic linking unless you have a very very good reason to use static linking. These libraries are installed by default on most peoples' systems anwyay.

If MinGW is using libstdc++-6.dll, then yea you would need to distribute that. If you want to avoid that, the solution is to using static linking as I mentioned just now.
 

Makai

Member
"Evolution" sounds synonymous with "supeior". Garbage collection is not superior to explicit memory management. It serves a different need, and while it might be superior in some aspects, it is inferior in others.
You're right, evolution isn't about superiority. It's about the adaptations of populations to survive in a niche. But the niche for manual memory management has shrunk significantly. I don't know what CornBurrito wants to make, but chances are good he can jump on the GC/ARC train and never look back.
 

Nelo Ice

Banned
Bleh having issues with what resume template to use. One of my dev friends mentioned he used this.
https://jsonresume.org/

Tried it out and have tried the slick and simple themes. Unless there's a better template, I'm thinking I should just go with one of these templates and call it day.

edit: Nvm I need to highlight some other stuff 1st since I'm going entry level. Going to look around for a diff template I can completely customize instead. Gah this is frustrating. Also doesn't help I'm so picky and want it to be perfect lol.
 
You're right, evolution isn't about superiority. It's about the adaptations of populations to survive in a niche. But the niche for manual memory management has shrunk significantly. I don't know what CornBurrito wants to make, but chances are good he can jump on the GC/ARC train and never look back.

Honestly it is just crap for a class assignment.
 

peakish

Member
I don't really understand what rich comparison method is, despite looking it up. I could really use some help or just general direction to figure this out this matching problem. Thanks in advance GAF!
The rich comparison is a way to get more control over a comparison between objects. In general your tiles will have some value (maybe in self.value?) which you can compare to tell if two tiles match by doing tile1.value == tile2.value.

What if you want to be sure that a set tile has a valid value before making the comparison? If both values are None the above comparison will be True, even if that's not what you want. You can write a function that performs some checks between two tiles to ensure that this is not the case and only then compares the values. This could be added to your Tile class as a method so that you can run tile1.equal(tile2) and perform this comparison within.

Now, I didn't know this up until looking at the documentation just now, but apparently Python's == operator works on objects by first looking for a method named __eq__ and if found, uses that. Pretty neat!
https://docs.python.org/3.5/reference/expressions.html#comparisons
https://docs.python.org/3.5/library/operator.html#module-operator

Edit: Apparently it's specifically the operator overloading that is referred to as being a rich comparison? My terminology game is off.
 

Koren

Member
Would I write that in code or type that in the command prompt beforehand? I read the same thing on a forum and didn't quite understand where I needed to do this.
Sorry, I wasn't clear enough... It's an option for the compiler, so you have to put it in your gcc invocation line among other options.

How do you compile your code exactly?

but I would strongly advise using dynamic linking unless you have a very very good reason to use static linking. These libraries are installed by default on most peoples' systems anwyay.
Not sure it's so common, since I've had this problem on all my Windows computers. Easy fix when you know what you're doing, especially if you have MinGW installed, but when you distribute the code, it make things more difficult. Windows support for shared libraries isn't great...

It's not distribution that's the worst, it's PATH management, version control (I've programs dinamically linked to different versions of the same DLL with the same name, that's awful), etc. Especially when people that use your software don't know how to handle this. I would say statically linking the standard library isn't an awful solution in this case, even if that makes the executable size grow a lot because of iostream.
 

Koren

Member
I don't really understand what rich comparison method is, despite looking it up. I could really use some help or just general direction to figure this out this matching problem. Thanks in advance GAF!
It suggests you to define a class for tiles, and a way to compare different tiles.

With an example, it'll be easier... Suppose you want to define a case independant string class (stupid idea, but it's the first I've had). The class can be defined as

Code:
class CaseIndpString :

    def __init__(self, string):
        self.string = string
    
    def __repr__(self) :
        return 'CaseIndpString("'+self.string+'")'
    
    def __str__(self) :
        return self.string

    ...

With this, if you try to compare two instances, you get :
Code:
In [329]: a = CaseIndpString('toto')

In [330]: b = CaseIndpString('toto')

In [331]: a == b
Out[331]: False

That's because the comparison is done using id(a) == id(b) (IIRC) since there's no way to compare two instances provided. You'll get True for a == b only if you defined b by b=a.

Now, add in the definition of the class the __eq__ method:
Code:
    def __eq__(self, other) :
        return other.string == self.string

With this:
Code:
In [334]: a = CaseIndpString('toto')

In [335]: b = CaseIndpString('toto')

In [336]: a == b
Out[336]: True

In [337]: b = CaseIndpString('Toto')

In [338]: a == b
Out[338]: False

That's a bit better, since it compare the data instead of the id. But it's still case dependant.

But, if you use

Code:
    def __eq__(self, other) :
        return other.string.lower() == self.string.lower()

You'll get:
Code:
In [341]: a = CaseIndpString('toto')

In [342]: b = CaseIndpString('Toto')

In [343]: a == b
Out[343]: True

Which is what I wanted from the start.


tldr: when you define a class, you can define a __eq__(self, other) method that returns a bool that will be used each time you try to compare two instances of the class.

It's similar to the idea of overloading operator== in C++.
 
I tried using Swift for a week, but it's too painful to code without full type inference.

Yeah as mentioned elsewhere, Swift is very hard to wrap your head around if you are used to C++ or Java(like in my case).
I feel that if I wanted to seriously learn Swift I should step away from iOS development (the two go hand in hand in almost every tutorial I found) until I get a good feel of how it works.
 

Makai

Member
Yeah as mentioned elsewhere, Swift is very hard to wrap your head around if you are used to C++ or Java(like in my case).
I feel that if I wanted to seriously learn Swift I should step away from iOS development (the two go hand in hand in almost every tutorial I found) until I get a good feel of how it works.
If you want to learn Swift, study Haskell for a few weeks first. Swift is great because it elegantly mixes a lot of functional concepts into a traditional C-family language. My problem is I jumped into the deep end of functional programming a couple months ago and it's painful to go back to object oriented programming. I definitely prefer Swift to C++ or Java because it at least meets me halfway.
 

Makai

Member
Specifically, I love strong-static typing without actually having to write any types. This is the GOAT language feature as far as I'm concerned. I couldn't believe it was possible when someone first described it to me. A couple months ago, my favorite language was C#, which only has type inference for method scope variables. Swift has type inference for all variables, so it's got C# beat. But you still have to manually type functions, argh.

I write this:

Code:
func multiply(a: Float, b: Float,  c: Float) -> Float{
    return a * b * c
}

and I want to go back to this:

Code:
let multiply a b c = a * b * c
 

nan0

Member
Bleh having issues with what resume template to use. One of my dev friends mentioned he used this.
https://jsonresume.org/

Tried it out and have tried the slick and simple themes. Unless there's a better template, I'm thinking I should just go with one of these templates and call it day.

edit: Nvm I need to highlight some other stuff 1st since I'm going entry level. Going to look around for a diff template I can completely customize instead. Gah this is frustrating. Also doesn't help I'm so picky and want it to be perfect lol.

Online-only? Otherwise moderncv with LaTeX.



It's so hard to go back to Java after 2 years of professional work with C#. No properties, no extension methods, no using(), no NuGet, no Visual Studio, packages tied to directory structure, fiddling with gradle scripts and incompatible packages for Android. Bleh.
 

Nelo Ice

Banned
Online-only? Otherwise moderncv with LaTeX.

Thanks for the heads up. I googled around and read briefly about LaTeX but had no idea wtf it meant lol. So guessing this article should be a good start?. http://www.maxburstein.com/blog/creating-resume-using-latex/
edit: Or this?.
http://www.latextemplates.com/template/moderncv-cv-and-cover-letter
Also yay I don't have to deal with Word. I was dreading having to make a nice Word resume. Funny thing is I find reading that LaTeX text editor way more readable and fun now compared to Word. And I used to love typing up docs since English was my best subject in school.
 
I agree it can be dauting the first time you do it, but honestly it's not that hard. And you're going to have to do this no matter if you're using Visual Studio, Makefiles, CMake, or anything else. The reason is that your program and the unit test runner are two separate executables that need to share the same code -- the code that is being tested.

The way you share code in this way is by creating libraries.

To get up and running the quickest, you can literally change your entire project to a static library. Right click the project node, choose Properties, click General, and set Configuration Type to Static Library (.lib). Change your main function to be called something else like RunProgram(), make a header file and declare RunProgram() in the header file. I'll just call this header file foo.h, but make it something more appropriate.

Now create a new project, this time an Application (.exe). But do it by right clicking the root node in Solution Explorer and choosing Add -> New Project. When VS finishes creating it, you'll now have two projects in the same solution. In your new application project, add a #include "foo.h", then in main() simply call RunProgram().

To make it automatically link the library into the application, right click the project node of the application, choose Build Dependencies -> Project Dependencies, and then click the checkbox for the library. You'll probably need to set the include directories in your exe project to find the folder where the include files for the library are. This is in Project Properties -> C/C++ -> General -> Additional Include Directories.

In a production environment, you would probably create a more realistic separation between your driver / application and your core functionality that you're testing, instead of simply having your main() function be one line that calls the static library. For example, command line parsing, user input, etc would all be handled in the application while processing and utility libraries etc would be handled in the library.

In any case, when you've got all this working, creating the unit test suite is not much different than the application. Make a new Application, add a dependency, go to the Linker and Include settings and add the appropriate paths for gtest, then #include files from your library and start using them in yoru tests.

One common solution for handling the situation with include file paths is for a project to do something like this:

Code:
project
|__ project.sln
|__ src
    |__ application
        |__ main.cpp
        |__ application.vcxproj
    |__ library1
        |__ lib1.cpp
        |__ lib1.vcxproj
    |__ library2
        |__ lib2.cpp
        |__ lib2.vcxproj
|__ include
    |__ application
    |__ library1
        |__ lib1.h
    |__ library2
        |__ lib2.h

Now, in every project, you set your Additional Include folders to $(SolutionDir)include. Then in your application.cpp, you can simply write something like this:

#include "library1/lib1.h"
#include "library2/lib2.h"

And it will automatically find it. This way you dont' have to go manually screw around with the include path settings for every single project. It's always exactly the same value for every project, just "$(SolutionDir)include".

Anyway this is a lot to take in the first time you do it, but it's fairly intuitive once you get used to it.
I wanted to follow up this post with two clarifications for anybody reading.
1. In VS2015 the include directories option is under Project > <PROJECT_NAME> Properties... > VC++ Directories
2. I had to add a reference to my program's library in my executable project. Right click the References listing in solution explorer > Add Reference > check your library > OK.
 
I wanted to follow up this post with two clarifications for anybody reading.
1. In VS2015 the include directories option is under Project > <PROJECT_NAME> Properties... > VC++ Directories
2. I had to add a reference to my program's library in my executable project. Right click the References listing in solution explorer > Add Reference > check your library > OK.

1. Do not touch that setting. That's the wrong place. I'm not at my computer now but go back to my original instructions and see if you can make it work with what i wrote. If not i can write more when I'm not on mobile
 
1. Do not touch that setting. That's the wrong place. I'm not at my computer now but go back to my original instructions and see if you can make it work with what i wrote. If not i can write more when I'm not on mobile
Not at my computer now either. I'll edit this post in an hour.

EDIT: Worked. The option seems like it does the same thing as the VC++ Directories. Any particular reason for going this route?
 
Not at my computer now either. I'll edit this post in an hour.

TL;DR - Don't use the one you used. Use Configuration Properties -> C/C++ -> General -> Additional Include directories.

Long explanation

So technically I guess it doesn't matter. But the place you've modified is a legacy holdover from old versions of MSVC, that has gradually changed throughout the years. The recommended way has always been to use the Additional Include Directories under C++. If you read the descriptions it gives a hint why:

The one you've set says:

Include Directories
Path to use when searching for include files while building a VC++ project. Corresponds to environment variable INCLUDE.

The other one says:

Additional Include Directories
Specifies one or more directories to add to the include path; separate with semi-colons if more than one (/I[path])

So the first one is setting an environment variable, and the second one is using a command line switch to the compiler. The second is better from a "purist" standpoint, because for example you could go to the Command Line tab, copy the command line out, run it, and get the same results as building from the IDE. Whereas if you use the other one you would get an error with the command line.

From a management standpoint, there's also one other benefit of using Additional Include Directories. Set your VC++ Directories / Include Directories to fff and set your C/C++ Additional Include Directories to sss. Now right click your main.cpp and hit properties. Notice there is no VC++ Include Directories here, only a C/C++ Additional Include Directories setting. And if you view it, it says sss. This is Visual Studio's property inheritance system, which is a really powerful way of specifying project settings. If you set something at the project level, it propagates down to all the children (i.e. source files), and you can override them on the individual file level if you want.

But if you use the first setting (the one I said not to use), it can't be overridden on a per-file level.

Anyway, you probably don't care about all of this stuff, but the point is, just get in the habit of doing it the right way, because one day it will make your life easier.
 
TL;DR - Don't use the one you used. Use Configuration Properties -> C/C++ -> General -> Additional Include directories.

Long explanation

So technically I guess it doesn't matter. But the place you've modified is a legacy holdover from old versions of MSVC, that has gradually changed throughout the years. The recommended way has always been to use the Additional Include Directories under C++. If you read the descriptions it gives a hint why:

The one you've set says:

Include Directories
Path to use when searching for include files while building a VC++ project. Corresponds to environment variable INCLUDE.

The other one says:

Additional Include Directories
Specifies one or more directories to add to the include path; separate with semi-colons if more than one (/I[path])

So the first one is setting an environment variable, and the second one is using a command line switch to the compiler. The second is better from a "purist" standpoint, because for example you could go to the Command Line tab, copy the command line out, run it, and get the same results as building from the IDE. Whereas if you use the other one you would get an error with the command line.

From a management standpoint, there's also one other benefit of using Additional Include Directories. Set your VC++ Directories / Include Directories to fff and set your C/C++ Additional Include Directories to sss. Now right click your main.cpp and hit properties. Notice there is no VC++ Include Directories here, only a C/C++ Additional Include Directories setting. And if you view it, it says sss. This is Visual Studio's property inheritance system, which is a really powerful way of specifying project settings. If you set something at the project level, it propagates down to all the children (i.e. source files), and you can override them on the individual file level if you want.

But if you use the first setting (the one I said not to use), it can't be overridden on a per-file level.

Anyway, you probably don't care about all of this stuff, but the point is, just get in the habit of doing it the right way, because one day it will make your life easier.
I totally care and that's all amazing to know. Thank you so much.
 

nan0

Member
Thanks for the heads up. I googled around and read briefly about LaTeX but had no idea wtf it meant lol. So guessing this article should be a good start?. http://www.maxburstein.com/blog/creating-resume-using-latex/
edit: Or this?.
http://www.latextemplates.com/template/moderncv-cv-and-cover-letter
Also yay I don't have to deal with Word. I was dreading having to make a nice Word resume. Funny thing is I find reading that LaTeX text editor way more readable and fun now compared to Word. And I used to love typing up docs since English was my best subject in school.

Yep, the second link uses the moderncv package.

Here is a good intro if you haven't used Latex before. Just be aware that Latex can have a very steep learning curve if things don't work the first time around. It's nice if it works but it will you make fail miserably if you encounter the cryptic error-messages and have no idea why you can't build.

Download Miktex, and I recommend Texmaker as editor. The first build of your document could take a bit longer, since it downloads the missing packages on demand.
 
Top Bottom