|
Thread Rules 1. This is not a "do my homework for me" thread. If you have specific questions, ask, but don't post an assignment or homework problem and expect an exact solution. 2. No recruiting for your cockamamie projects (you won't replace facebook with 3 dudes you found on the internet and $20) 3. If you can't articulate why a language is bad, don't start slinging shit about it. Just remember that nothing is worse than making CSS IE6 compatible. 4. Use [code] tags to format code blocks. |
On June 15 2015 22:40 BisuDagger wrote:Show nested quote +On June 15 2015 22:33 Acrofales wrote:On June 15 2015 22:11 BisuDagger wrote:On June 15 2015 22:07 inn5013orecl wrote:On June 15 2015 21:05 BisuDagger wrote:Okay this is a pretty odd question and either there is no answer or it is stupidly obvious. Reply in terms of C++, C# please: If I have a function OnMouseDown() and it calls a function IsUISelected() such that it looks like this: void OnMouseDown() { IsUISelected(); }
If IsUISelected resolves to true in it's function I need to break out out of the OnMouseDown() function instead of continuing. I'm trying to simply this statement. Simplying the state is purely just a curiosity not a necessity. void OnMouseDown() { if (GlobalVariables.UISelected()) { return; } }
Pretty sure that's as simple as you're going to get. Return pass control back to the caller of OnMouseDown(), effectively exiting out of the function. In this case, works exactly like a break statement in a loop. void OnMouseDown() { if(IsUISelected()) // IsUISelected() value returned return; }
That's what I thought. I just have to use this check in so many damn places I was trying to save white space. Oh well lol. edit: The reason I keep the brackets is to match a coding standard of another companies programmers I have to work with from time to time. Restructure your program to require less of these checks? Or suck it up. Honestly, I can't think why you wouldn't just put all of that check and return statement on a single line (including {}s). Hell, you can add a line of commentary above it and still save 2 lines if you do it that way. //Break out of mouse handler if UI is selected if(IsUISelected()) { return; }
is imho just as clear as the 4-line version (although the line of commentary is not necessary at all, the line is pretty self-explanatory. Better commentary would be a reminder why breaking out of the mouse handler is the proper functioning of the program). As I mentioned in my edit. For at least this project I'm matching a coding standard for another company. I'm the lead programmer within my company and I 100% agree with you, but the other companies guidelines are "always use brackets for readability" and "Don't comment code unless absolutely necessary to reduce clutter.". I've done really well in my profession by following the technical outlines of a company (even if you disagree) instead of fighting the system.
Yup, no matter how annoying they are, it's important to follow the set coding guidelines. In every company, there are some very annoying rules, e.g. in my last company we had to use an hungarian naming scheme where every object was $objSomething, which was really useless because almost everything was an object, you just didn't know what kind of object. However, in the end it's better to have everyone write code in the same way, even if it has some weird quirks, than have wildly different styles in the same code base. You can slowly change the style guidelines to make exceptions for guard clauses when you have enough influence and support, but until then it's always best to stick to what exists.
Joel Spolsky put it nicely in his article about hungarian notation
When you start out as a beginning programmer or you try to read code in a new language it all looks equally inscrutable. Until you understand the programming language itself you can’t even see obvious syntactic errors.
During the first phase of learning, you start to recognize the things that we usually refer to as “coding style.” So you start to notice code that doesn’t conform to indentation standards and Oddly-Capitalized variables.
It’s at this point you typically say, “Blistering Barnacles, we’ve got to get some consistent coding conventions around here!” and you spend the next day writing up coding conventions for your team and the next six days arguing about the One True Brace Style and the next three weeks rewriting old code to conform to the One True Brace Style until a manager catches you and screams at you for wasting time on something that can never make money, and you decide that it’s not really a bad thing to only reformat code when you revisit it, so you have about half of a True Brace Style and pretty soon you forget all about that and then you can start obsessing about something else irrelevant to making money like replacing one kind of string class with another kind of string class.
The code style doesn't really matter as long as it's good, readable code that works, so you might as well stick to the given rules and not waste your time arguing about braces or no braces.
|
Does anyone here have any experience with QNX embedded systems?
|
Look at this gem. Maybe we will see an enterprise java application generation simulator someday.
|
On June 14 2015 20:11 Nesserev wrote:Show nested quote +On June 14 2015 14:28 necrosexy wrote: any recommended resources for learning unix and shell programming? 'The Linux Command Line' from No Starch Press, combined with the resource that Frolossus linked above, will be all you ever need. Btw, No Starch Press has some of the best and most enjoyable books in the business. Check out their website: http://www.nostarch.com/ Thanks!!
|
@necrosexy:
Also check this guide here out:
http://mywiki.wooledge.org/BashGuide
It has pages that are good to bookmark, for example this here:
http://mywiki.wooledge.org/BashSheet
Depending on what you want to do, one of the pages on that site might be very important to bookmark:
http://mywiki.wooledge.org/Bashism?highlight=(bashism)
The background for what's on that page is: bash is not the default shell on a lot of systems. For Linux, Debian and Ubuntu use something simpler, and what you'll find on for example a router also won't be bash. The BSD's similarly don't use it. So if you write a script targeting the system's /bin/sh, you should be careful to not use features that only work if /bin/sh = bash. How to translate bash to plain sh is what's on that page.
|
On June 18 2015 18:08 Ropid wrote:@necrosexy: Also check this guide here out: http://mywiki.wooledge.org/BashGuideIt has pages that are good to bookmark, for example this here: http://mywiki.wooledge.org/BashSheetDepending on what you want to do, one of the pages on that site might be very important to bookmark: http://mywiki.wooledge.org/Bashism?highlight=(bashism)The background for what's on that page is: bash is not the default shell on a lot of systems. For Linux, Debian and Ubuntu use something simpler, and what you'll find on for example a router also won't be bash. The BSD's similarly don't use it. So if you write a script targeting the system's /bin/sh, you should be careful to not use features that only work if /bin/sh = bash. How to translate bash to plain sh is what's on that page. i see, thanks!
|
Guys, how do you structure C projects? I've never written anything complex in C before but I plan on changing that and was wondering if there is any kind of "standard" folder structure or anything like that.
I was thinking about something along the lines of this:
/bin -- executables go here /config -- makefiles, misc config files /data -- sqlite databases, images etc. /scripts -- Lua and other stuff /src /ext -- external libraries (other people's stuff and such) /lib -- actual c code goes here /sys -- headers go here
Would that be any good? Or should I perhaps keep config, data and scripts inside the src folder?
Edit:
And while we're at it, could anyone help me out a bit with the basic stuff?
#include <stdio.h> #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)); #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y));
// prototypes int factorial(int n); int* fill_range(int x, int size); int* fill_range_reverse(int x, int size); int* irange(int x, int y);
int main() { int fac = factorial(5); int* range1 = irange(1, 10); int* range2 = irange(10, 1); int i = 0;
printf("Factorial of 5 is: %d\n", fac); for (i = 0; i < 10; ++i) { printf("Normal range %d: %d\n", i, range1[i]); } for (i = 0; i < 10; ++i) { printf("Reverse range %d: %d\n", i, range2[i]); }
return 0; }
int factorial(int n) { if (n < 2) return 1; return (n * factorial(n - 1)); }
int* fill_range(int x, int size) { int range[size]; int i = 0; while (i < size) { range[i] = x;
i += 1; x += 1; } return range; }
int* fill_range_reverse(int x, int size) { int range[size]; int i = 0; while (i < size) { range[i] = x; i += 1; x -= 1; } return range; }
int* irange(int x, int y) { int size = MAX(x, y) - MIN(x, y) + 1; if (x > y) return fill_range_reverse(x, size); return fill_range(x, size); }
main.c: In function 'fill_range': main.c:54:5: warning: function returns address of local variable [-Wreturn-local-addr] return range; ^ main.c: In function fill_range_reverse': main.c:70:5: warning: function returns address of local variable [-Wreturn-local-addr] return range; ^
I must say that I'm at a loss here... Haven't touched C for years and I pretty much suck hard at it now... I'm too spoiled with new toys to remember exactly how all the static and const stuff worked in C, should I malloc the range initializers first?
Edit2:
Nevermind, sometimes I'm just too dumb...
+ Show Spoiler [fixed code] + #include <stdio.h> #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)); #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y));
// prototypes int factorial(int n); int* fill_range(int x, int size, int* range); int* fill_range_reverse(int x, int size, int* range); int* irange(int x, int y);
int main() { int fac = factorial(5); int* range1 = irange(1, 10); int* range2 = irange(10, 1); int i = 0;
printf("Factorial of 5 is: %d\n", fac); for (i = 0; i < 10; ++i) { printf("Normal range %d: %d\n", i, range1[i]); } for (i = 0; i < 10; ++i) { printf("Reverse range %d: %d\n", i, range2[i]); }
return 0; }
int factorial(int n) { if (n < 2) return 1; return (n * factorial(n - 1)); }
int* fill_range(int x, int size, int* range) { int i = 0; while (i < size) { range[i] = x;
i += 1; x += 1; } return range; }
int* fill_range_reverse(int x, int size, int* range) { int i = 0; while (i < size) { range[i] = x; i += 1; x -= 1; } return range; }
int* irange(int x, int y) { int size = MAX(x, y) - MIN(x, y) + 1; int range[size]; if (x > y) return fill_range_reverse(x, size, range); return fill_range(x, size, range); }
|
On June 20 2015 06:24 Manit0u wrote:Guys, how do you structure C projects? I've never written anything complex in C before but I plan on changing that and was wondering if there is any kind of "standard" folder structure or anything like that. I was thinking about something along the lines of this: /bin -- executables go here /config -- makefiles, misc config files /data -- sqlite databases, images etc. /scripts -- Lua and other stuff /src /ext -- external libraries (other people's stuff and such) /lib -- actual c code goes here /sys -- headers go here
Would that be any good? Or should I perhaps keep config, data and scripts inside the src folder?
I've got a ton of experience with QNX, though it's been a few years I actually did any projects with it since now I work for a competitor.
That directory structure looks fine, I might put your actual C code in /src, and put external libraries in /lib and headers in /src/include or just /include. Your Makefile and README should go in the root directory, not /config, but that doesn't mean you shouldn't have a folder for storing random configuration files in it as well, which may include other Makefiles being imported with various compiler options being defined.
Depending on what your project's end output file will be, I prefer to place my project folder within the same folder as the examples for the OS. The benefit is that a lot of your code is going to be copied over from those examples, and that you can put the entire OS in version control along with your project (which you should do, in case you accidentally change something you shouldn't have).
+ Show Spoiler +If you want to open source your project, don't do this if you had to have a license to decrypt the OS libraries in the first place to install them. If the OS you are using is already open source, consider branching it instead of making a new repository
You'll also need a obj/ folder for storing intermediate object files.
For those who missed the change in his code, the warning was because he stored an array on the stack, then returned it, so if the calling function tried to use that array, it could point to completely different data stored on the stack later.
|
|
On June 20 2015 07:33 Nesserev wrote:Well, you're supposed to dynamically allocate the memory for the array. // creates a local array on the stack int range[size];
...
return range; // range is "destroyed" at the end of this function :(
// pointer used to point to array int* d_range;
// create dynamically allocated array on heap d_range = (int *)malloc(sizeof(int) * size);
...
return d_range;
Who is going to free() that malloc()?
Manit0u's fixed implementation allows the user of the function to allocate the memory where they want, instead of forcing it onto the heap.
|
On June 20 2015 07:21 RoyGBiv_13 wrote:Show nested quote +On June 20 2015 06:24 Manit0u wrote:Guys, how do you structure C projects? I've never written anything complex in C before but I plan on changing that and was wondering if there is any kind of "standard" folder structure or anything like that. I was thinking about something along the lines of this: /bin -- executables go here /config -- makefiles, misc config files /data -- sqlite databases, images etc. /scripts -- Lua and other stuff /src /ext -- external libraries (other people's stuff and such) /lib -- actual c code goes here /sys -- headers go here
Would that be any good? Or should I perhaps keep config, data and scripts inside the src folder? I've got a ton of experience with QNX, though it's been a few years I actually did any projects with it since now I work for a competitor. That directory structure looks fine, I might put your actual C code in /src, and put external libraries in /lib and headers in /src/include or just /include. Your Makefile and README should go in the root directory, not /config, but that doesn't mean you shouldn't have a folder for storing random configuration files in it as well, which may include other Makefiles being imported with various compiler options being defined. Depending on what your project's end output file will be, I prefer to place my project folder within the same folder as the examples for the OS. The benefit is that a lot of your code is going to be copied over from those examples, and that you can put the entire OS in version control along with your project (which you should do, in case you accidentally change something you shouldn't have). + Show Spoiler +If you want to open source your project, don't do this if you had to have a license to decrypt the OS libraries in the first place to install them. If the OS you are using is already open source, consider branching it instead of making a new repository You'll also need a obj/ folder for storing intermediate object files.
With the structure I wasn't asking about QNX specifically. I'm just toying around with ANSI C in my leisure time.
I was asking about QNX because a friend of mine asked me for help and I simply can't refuse stuff that involves learning some new code. The task at hand was relatively simple but I've found QNX's online documentation to be pretty lacking (as in, requiring you to have really good knowledge of the system to understand it, at which point you probably don't need it). I also hat it when they always seem to do for( ; ; ) instead of while(true) or something. But I digress...
The problem he had to solve was the password/pin thingie. Where you give the user a message, wait 5 seconds for input and reset ad infinitum. The task specifically asked to use the alarm() function. While making a simple loop and doing alarm(5) inside of it is easy, actually handling the alarm is not. From what I read in the docs, when the time for the alarm elapses, it sends the SIGALRM which kills the current process, thus exiting the loop and all. I've read that you should handle this signal with sigaction() or somesuch but I couldn't really find a way to make sigaction() resume/restart the loop.
Could you shed some light on the matter?
On June 20 2015 07:35 RoyGBiv_13 wrote: Manit0u's fixed implementation allows the user of the function to allocate the memory where they want, instead of forcing it onto the heap.
Is it a bad thing?
Edit:
Also, the code purist in my heart tells me to refactor the code, remove fill_range_reverse and simply pass another argument to the fill range function (a boolean) that controls incrementation/decrementation inside of the loop to remove code duplication.
+ Show Spoiler [like so] + #include <stdio.h> #define MIN(X, Y) (((X) < (Y)) ? (X) : (Y)); #define MAX(X, Y) (((X) > (Y)) ? (X) : (Y));
// prototypes int factorial(int n); int sum(int n); int check_increment(int x, int reverse) int* fill_range(int x, int size, int* range, int reverse); int* irange(int x, int y);
int main() { int fac = factorial(5); int* range1 = irange(1, 10); int* range2 = irange(10, 1); int i = 0;
printf("Factorial of 5 is: %d\n", fac); for (i = 0; i < 10; ++i) { printf("Normal range %d: %d\n", i, range1[i]); } for (i = 0; i < 10; ++i) { printf("Reverse range %d: %d\n", i, range2[i]); }
return 0; }
int factorial(int n) { if (n < 2) return 1; return (n * factorial(n - 1)); }
int sum(int n) { return ((n * (n + 1)) / 2); }
int check_increment(int x, int reverse) { return reverse ? x -= 1 : x += 1; }
int* fill_range(int x, int size, int* range, int reverse) { int i = 0; while (i < size) { range[i] = x;
i += 1; x = check_increment(x, reverse); } return range; }
int* irange(int x, int y) { int size = MAX(x, y) - MIN(x, y) + 1; int range[size]; return x > ? fill_range(x, size, range, 1) : fill_range(x, size, range, 0); }
|
|
On June 20 2015 07:35 Manit0u wrote:Show nested quote +On June 20 2015 07:21 RoyGBiv_13 wrote:On June 20 2015 06:24 Manit0u wrote:Guys, how do you structure C projects? I've never written anything complex in C before but I plan on changing that and was wondering if there is any kind of "standard" folder structure or anything like that. I was thinking about something along the lines of this: /bin -- executables go here /config -- makefiles, misc config files /data -- sqlite databases, images etc. /scripts -- Lua and other stuff /src /ext -- external libraries (other people's stuff and such) /lib -- actual c code goes here /sys -- headers go here
Would that be any good? Or should I perhaps keep config, data and scripts inside the src folder? I've got a ton of experience with QNX, though it's been a few years I actually did any projects with it since now I work for a competitor. That directory structure looks fine, I might put your actual C code in /src, and put external libraries in /lib and headers in /src/include or just /include. Your Makefile and README should go in the root directory, not /config, but that doesn't mean you shouldn't have a folder for storing random configuration files in it as well, which may include other Makefiles being imported with various compiler options being defined. Depending on what your project's end output file will be, I prefer to place my project folder within the same folder as the examples for the OS. The benefit is that a lot of your code is going to be copied over from those examples, and that you can put the entire OS in version control along with your project (which you should do, in case you accidentally change something you shouldn't have). + Show Spoiler +If you want to open source your project, don't do this if you had to have a license to decrypt the OS libraries in the first place to install them. If the OS you are using is already open source, consider branching it instead of making a new repository You'll also need a obj/ folder for storing intermediate object files. With the structure I wasn't asking about QNX specifically. I'm just toying around with ANSI C in my leisure time. I was asking about QNX because a friend of mine asked me for help and I simply can't refuse stuff that involves learning some new code. The task at hand was relatively simple but I've found QNX's online documentation to be pretty lacking (as in, requiring you to have really good knowledge of the system to understand it, at which point you probably don't need it). I also hat it when they always seem to do for(;  instead of while(true) or something. But I digress... The problem he had to solve was the password/pin thingie. Where you give the user a message, wait 5 seconds for input and reset ad infinitum. The task specifically asked to use the alarm() function. While making a simple loop and doing alarm(5) inside of it is easy, actually handling the alarm is not. From what I read in the docs, when the time for the alarm elapses, it sends the SIGALRM which kills the current process, thus exiting the loop and all. I've read that you should handle this signal with sigaction() or somesuch but I couldn't really find a way to make sigaction() resume/restart the loop. Could you shed some light on the matter?
Hmm, this is actually closer to pure POSIX than anything QNX related, so you're in luck because the documentation for that is actually really well filled out (but never in one place).
Signals won't actually kill the process, it will continue to run after handling the signal, so if you're already in an infinite spin loop, you won't get out of it. Instead, have the signal modify a global variable that the spin loop is based off of (instead of while(true), use while(spinning), where spinning is volatile) http://stackoverflow.com/questions/14042647/using-sigaction-and-alarm-to-break-from-infinite-loop
|
Thanks, that helps a ton.
|
That fixed code still has the exact same bug btw, just expertly hidden from the compiler.
|
On June 20 2015 08:10 iaretehnoob wrote: That fixed code still has the exact same bug btw, just expertly hidden from the compiler.
Which bug?
|
|
And how should I remedy this?
Edit:
Nevermind. I see my error. I'll think how to solve this.
Edit2:
Should I declare range as global variable, malloc it inside the irange function and free it after use? I was kind of hoping I could avoid declaring globals or assigning array size before calling the irange
|
You could use malloc() in irange() to create your int[] range on the heap instead of the stack, then perhaps rename irange() to alloc_irange() to make it clear that the user of this function has to free() the buffer in the future.
Or you could put the malloc() in main(), so that it's in the same block of your code where you'll also have to do the free(). In that case you might want to have some sort of info function that calculates the required size to use with malloc() for certain x, y values.
|
And what if I put range and other stuff into a struct? Would that be a good idea?
Somehow I completely forgot about structs...
|
|
|
|