C++ new() operator
June 28, 2012 at 7:17 pm | Posted in C++, Programming | Leave a commentTags: C language, C++, programmer, Programming
I was working on adding some features to a software written as a mixture of C and C++ and I came to realize many C++ programmers write C in C++. Take a look at this:
#include <iostream>
#include <new>
int main()
{
char * t = new char[1];
if(!t)
{
printf("Memory Exhausted\n");
exit(EXIT_FAILURE);
}
t[0] = 'A';
printf("t[0] = %c\n", t[0]);
return 0;
}
Everything looks fine and g++ (on RHEL 5) even compiles/runs with flags (-ansi -pedantic -Wall -Wextra) and without any warning/error. Program just seems to be technically correct (which it is seems like but isn’t) and prints the value inside array as expected. Now let us take a more basic look at this. Why we are using printf() in a C++ program when C++ has its own standard library ? The program we have writen is actually C in C++. It is like using a powerful mechanism and throwing all the powerful tools/methods away because you don’t want to know about them. Many industrial programmers don’t want to know about it because life goes on fine without knowing about it and they are still earning much higer salaries without knowing it (and they will keep on increasing their monthly income by impressing HR guys with a bag of languages and big projects on their Resumes). Hence Why bother ? Wrong reasons. If you are really looking for laziness then find it elsewhere because laziness equals to the amount of bugs in programming. Rewrite it the C++ way:
#include <iostream>
#include <new>
int main()
{
char * t = new char[1];
if(!t)
{
std::cerr << "Memory Exhausted" << std::endl;
exit(EXIT_FAILURE);
}
t[0] = 'A';
std::cerr << "t[0] = " << t[0] << std::endl;
return 0;
}
It is still not C++. What we call it now is a mixture of C and C++ provided the programmer does not know about C++ much. He was basically a C programmer and was either forced to use C++ compiler or was too lazy to know C++. Again it compiles/runs fine as it looks technically correct. check out new operator in section 18.6.1 of current C++ standard (you can check out draft of the standard, just google for N3337.pdf). new does not return NULL, hence the check is wrong. new throws bad_alloc() if it can’t allocate memory. Hence the technically correct version looks like this:
#include <iostream>
#include <new>
int main()
{
char * t;
try { t = new char[1]; }
catch(bad_alloc)
{
std::cerr << "Memory Exhausted" << std::endl;
exit(EXIT_FAILURE);
}
return 0;
}
This will never compile. Why ? Because you did not mention where bad_alloc is coming from. It is in standard library, hence you need to use std::bad_alloc. If you think you simply dump the whole standard namespac by using using namespace std in there, then you really need to read C++ FAQs before writing C++ programs any further. You need to think why I am writing std::cout instead of usual cout used by typical Indian programmers. Let us try one more time:
#include <iostream>
#include <new>
int main()
{
char * t;
try { t = new char[1]; }
catch(std::bad_alloc)
{
std::cerr << "Memory Exhausted" << std::endl;
exit(EXIT_FAILURE);
}
t[0] = 'A';
std::cout << "t[0] = " << t[0] << std::endl;
return 0;
}
This seems like pure C++. Yes, it is. Sure ? We still have one general programmig problem remaining to be solved. If you call exit() then you are not being practical, e.g. you wrote a client which connects to a server. One of the users of your software is connected and suddenly he is out of memory, then you program will just disconnect without saying a bye. Server will not like it and may log it as an error or will wait for an automatic timeout.
That was a general exmaple, let us look at more technical example. When a game adjusts your resolution to 640×480 and resets it back to normal (say 1280×1024), it will call destructor on 640×480 in resetting but it will not do so because exit() will not call the destructor, you will get stuck in a low resolution screen. It happens when some games crash without throwing an exception and rolling back the stack. So what do you do ? Let us try one last time to write pure C++ code
#include <iostream>
#include <new>
int main()
{
char * t;
try { t = new char[1]; }
catch(std::bad_alloc)
{
std::cerr << "Memory Exhausted" << std::endl;
return EXIT_FAILURE;
}
t[0] = 'A';
std::cout << "t[0] = " << t[0] << std::endl;
return 0;
}
NOTE: There is still a way if you want to check for NULL (instead of catch()ing an exception). You can use the nothrow version of new operator which returns a NULL pointer instead of throwing an exception but you have to mention it explicitly.
Copyright © 2012 Arnuld Uttre, Village – Patti, P.O – Manakpur, Tehsil – Nangal, Distt. – Ropar, Punjab (INDIA)
Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this notice, and the copyright notice, are preserved.
The Real Programmer
March 19, 2012 at 11:04 am | Posted in Programming | Leave a commentTags: C++, decac, Java, Lisp, programmer, Programming
I was checking out what new language to learn. There are several points here:
- Language: Most newbies or less experienced programmers think of learning a new langauge and thats it. They think learning more languages will make them better programmer. Unfortunately this is not true.
- New Paradigm : Other experiences programmers want to learn a new paradigm which will change their way of thinking and make thema better programmer rather than a programmer who knows several languages. He thinks that learning a language like C++ wil automatically make him an OO expert. Sigh…. he got immature mindset too.
- Reality Check : No matter what a programmer wants to do, either of the above or both, his thoughts are crushed by the reality of the software as an industry. He works whole day and then he has a family and he wants to have a life too and there are only 24 hours in a day. Out of all this mess and busy schedule, he starts thinking that he can not afford to spend time learning a langauge which does not give him a rise in his income.
- RealProgrammer : . Now there is another breed of programmers, which I call real programmers (I am one of them. What you think ? … No ? … c’mon just believe it because I am the author of this post
) Here the real programmer, I mean the one who does not believe in quick fixes, the one who started programming because he likes it, because he is happily willing to live next 20, 30, 40, 50 years of his life writing code, THAT ONE decieds to go long term. Rather than deciding on income-factor he goes with programming-factor, he decied to learn new-paradigm, decides to check out something unheard in industry but heard a lot from the mouths of good programmers.
Learning programming for income is like a adding one more language to your Resume and that stops right there and it adds not much to your skill as programmer. I think you must aim for getting more out of the time you spend, you must aim differently, you must aim what your common-sense thinks is right. Unfortunately most programmers don’t have that common-sense because industry is full of programmers who do it for money just like a fruit-seller who sells fruits for money but himself does not eat much of them because he is not interested in how fruits lead to good health. My advice will be wathcing and observing what all brilliant programmers are doing from years and learn from them. Thats what I do.
I am a C Programmer and I wanted that new language to help rise in my career too. Of course the choice came out to be C++. But C++ is almost in the same paradigm as C plus more. C is procedural while C++ has OO and generic paradigms added to and it is designed in such a way that you can add a lot of other paradigms to it but C and C++ belong to almost same kind of mindset. I wanted to write a microkernel for Hurd, hence I dwelled into other languages like BitC and decac etc. but then again lack of time and my focus on what can I do to become better programmer and use my time with maximum productivity. Here are the options I think I have found:
- Haskell
- ErLang
- Common Lisp
- Python
- Ruby
- Ada
- Caml
- BitC
- decac
- Eiffell
- RISC Assembly
- D Programming Langauge
- Prolog
- C++
Now, I can’t learn everything, it will take 2 lives to finish this list off. So after lot sof googling, lots of readings of practical views, research papers etc etc I selected Common-Lisp. Lisp is 2nd oldest language still in existance after FORTRAN. Lisp has a changed a lot since then. Code and Data are same in Lisp. Many concepts were developed first in Lisp and then in other languages e.g. garbage collection. You can write Lisp code which will write Lisp code, its like creating a new language yourself. I learned about recursion in 7 days which I struggled to learn for 4 years with C and C++. I learned Binary-Search in 5 minutes which I am trying from last year to understand with C, in C you struggle more with how to write in C rather than the abstraction of the problem and its solution. (No wait… I am not attacking C, Not at all. C is a great language to learn to know about pointers which Lisp intelligently hides. You must learn both C and Common-Lisp if you are serious about programming.) For Managers Common-Lisp has OO and the next generation fancy (but practical) words e.g. MOP (Meta-Object Protocol if you have never heard of it). There are lot of strange languages and I don’t know why Common-Lisp impressed me so much. So far I have seen only one company in India using it.
Bottom line is: If you want a job, learn Java, C#, .NET or C++ . If you want to be a better programmer and willing to spend next 20 years of your life writing code, you better learn C and Common-Lisp and yeah arrays and pointers are not same and code is data in Lisp. The point is not to run after money but specizlized skills in programming. Specialized skill over long-term attracts money automatically.
Copyright © 2012 Arnuld Uttre, Village – Patti, P.O – Manakpur, Tehsil – Nangal, Distt. – Ropar, Punjab (INDIA)
Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this notice, and the copyright notice, are preserved.
The Craft of Programming
August 31, 2009 at 11:16 am | Posted in Patterns, Programming | Leave a commentTags: C++, esr, Lisp, Programming, quotes, RMS, software quotes
Here are some quotes I have gathered over the years. They are written by some of the best known Programmers and Hackers with occasionally some very good programmers thrown in, if not great. They inspired me, changed the way I look at programming and especially at some programming languages and methods to solve problems:
“Any sufficiently complicated C or Fortran program contains an ad hoc informally-specified bug-ridden slow implementation of half of Common Lisp.” — Philip Greenspun
“Something we didn’t want was an object-oriented language. OO languages remain a popular fad, but our experience using C++ in the EROS system was that it actively got in the way of understanding what was going on.”
– The Origins of the BitC Programming Language
When you want to use a language that gets compiled and runs at high speed, the best language to use is C. Using another language is like using a non-standard feature. — GNU Coding Standards
“First off, I’d suggest printing out a copy of the GNU coding standards,
and NOT read it. Burn them, it’s a great symbolic gesture.” — Linux kernel coding guidelines
“C++ will rot your brain” — someone from #lisp at irc.freenode.net
“pointer arithmetic and array indexing [that] are equivalent in C, pointers and arrays are different.” – Wayne Throop
“An array is not a pointer, nor vice versa” — Steve Summit in C FAQs
“Attitude is no substitute for competence” — Eric S. Raymond in How to become a Hacker
Q: I’m having problems with my Windows software. Will you help me?
A: Yes. Go to a DOS prompt and type “format c:”. Any problems you are experiencing will cease within a few minutes.
– Eric S. Raymond
“This answer cannot be decided by current law—the law should conform to ethics, not the other way around” — Richard M. Stallman
“Lisp is a programmable programming language.” – John Foderaro, CACM, September 1991
Q: “My company needs a proprietary operating system to get a competitive edge.”
A: GNU will remove operating system software from the realm of competition. You will not be able to get an edge in this area, but neither will your competitors be able to get an edge over you. You and they will compete in other areas, while benefiting mutually in this one.
“There is nothing wrong with wanting pay for work, or seeking to maximize one’s income, as long as one does not use means that are destructive. But the means customary in the field of software today are based on destruction.” — Richard M. Stallman
“Haskell saves lives”
“In general, functional languages offer powerful new ways to encapsulate abstractions” — Haskell Wiki
“I invented the term ‘Object-Oriented’, and I can tell you I did not have C++ in mind.” — Alan Kay.
“C++ is the only current language making COBOL look good” — Bertrand Meyer
“It’s 5.50 a.m…. Do you know where your stack pointer is ?” — Anonymous
“I understand the philosophy that developer cycles are more important than cpu cycles, but frankly that’s just a bumper-sticker slogan and not fair to the people who are complaining about performance.” – Joel Spolsky
“The standard — either one — is not the End of All C. Writing ‘strictly conforming’ C code, however, has an enormous benefit.” — Chris Torek
“Wait a minute, I want to modify that statement. I’m not claiming, in this particular article, that there’s anything wrong with Java as an implementation language. There are lots of things wrong with it but those will have to wait for a different article.” — Joel Spolsky
“Without understanding functional programming, you can’t invent MapReduce, the algorithm that makes Google so massively scalable” — Joel Spolsky
“It [Java] might be successful – after all, MS DOS was – and it might be a profitable thing for all your readers to learn Java, but it has no intellectual value whatsoever. Look at their implementation of hash tables. Look at the sorting routines that come with their “cool” sorting applet. ” – Alexander Stepanov
“Java isn’t platform independent; it is a platform. Like Windows, it is a proprietary commercial platform. ” — Bjarne Stroustrup
Copyright © 2006, 2007, 2008 Arnuld Uttre, #331/type-2/sector-1, Naya Nangal, Distt. – Ropar, Punjab (INDIA) – 140126
Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this notice, and the copyright notice, are preserved.
A LIFO in C using Singly-Linked List
May 25, 2009 at 11:03 am | Posted in Hacking | Leave a commentTags: C++, LIFO, Linked List
Here is the implementation of a LIFO in C using Singly-Linked list. Remember pop() may look different than what you will read in an academic book. Actually, I think if my program malloc()s some memory then its my responsibility to free() it while some others may not agree on that and will stress that pop() should only give the element, not free() it. Based on my experience with programming I completely disagree, when you give someone a program and tell him what it does, the other person uses it like a black-box, he does not know what is inside the program or how it is working, he just needs to know what this programs requires as input and what is its output. In the end, the only thing he needs to know is it should work fine without giving any strange errors on his LCD monitor. Thats it, and that shifts all the responsibility of handling the program back to the programmer, not the user, which is inherently a good idea I think. If you are a C programmer and you don’t know where your memory is going and what the pointers are doing and where they are at one point in your program, you should forget working in C. As usual, you can always find the original discussion on Usenet.
/* A Stack implementation of a singly linked list with 4 operations: Pop, Push, Top and Print elements in the list.
*
* VERISON 0.4
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
enum { STACK_ARR_SIZE = 10 };
struct my_stack
{
char arrc[STACK_ARR_SIZE]; /* Thar array must not have more than (STACK_ARR_SIZE - 1) elements */
struct my_stack* next;
};
struct stack_list
{
struct my_stack* head;
};
struct stack_list* push( struct stack_list*, const char* );
struct stack_list* pop( struct stack_list* );
struct my_stack* top( struct stack_list* );
struct my_stack* make_null( struct stack_list* );
struct my_stack* is_empty( struct stack_list* );
struct stack_list* stack_new( void );
void stack_print( const struct stack_list* );
void stack_print_element( const struct my_stack* );
struct stack_list* stack_free( struct stack_list* );
int main( void )
{
struct my_stack* p = NULL;
struct stack_list* ms = NULL;
ms = stack_new();
stack_print(ms);
push(ms, "comppppppppppppppppp");
push(ms, "(dot)");
push(ms, "lang");
push(ms, "(dot)");
push(ms, "c");
stack_print(ms);
pop(ms);
p = top(ms);
stack_print(ms);
stack_free(ms);
free(ms);
ms = NULL;
return 0;
}
struct stack_list* push(struct stack_list* s, const char* c )
{
struct my_stack* p = malloc( 1 * sizeof *p );
if( NULL == p )
{
fprintf(stderr, "malloc() failed\n");
return s;
}
/* If use gave us more characters than what we want, then its his problem */
if( strlen(c) < STACK_ARR_SIZE ) strcpy(p->arrc, c);
p->next = NULL;
if( NULL == s )
{
fprintf(stderr, "Stack not initialized ?\n");
free(p);
return s;
}
else if( NULL == s->head )
{
/* printf("Stack is Empty, adding first element\n"); */
s->head = p;
return s;
}
else
{
/* printf("Stack not Empty, adding in front of first element\n"); */
p->next = s->head;
s->head = p; /* push new element onto the head */
}
return s;
}
struct stack_list* pop( struct stack_list* s )
{
struct my_stack* p = NULL;
if( NULL == s )
{
printf("There is no stack list ?\n");
}
else if( NULL == s->head )
{
printf("There is no element on the stack\n");
}
else
{
p = s->head;
s->head = s->head->next;
free(p);
}
return s;
}
struct my_stack* top( struct stack_list* s)
{
if( NULL == s )
{
printf("There is no stack list ?\n");
return NULL;
}
else if( NULL == s->head )
{
printf("There is no element on the stack\n");
}
return s->head;
}
/* Make a Stack empty */
struct my_stack* make_null( struct stack_list* s )
{
if( NULL == s )
{
printf("Can not make NULL when there is no Stack List\n");
return NULL;
}
else if( NULL == s->head )
{
printf("Stack is already Empty\n");
}
else
{
stack_free(s);
}
return s->head;
}
struct my_stack* is_empty( struct stack_list* s )
{
if( NULL == s )
{
printf("There is no Stack\n");
return NULL;
}
else if( NULL == s->head )
{
printf("Stack is Empty\n");
}
else
{
printf("Stack is not Empty\n");
}
return s->head;
}
/* ---------- small helper functions -------------------- */
struct stack_list* stack_free( struct stack_list* s )
{
if( NULL == s )
{
printf("Can't free a NULL stack list\n");
}
while( s->head ) pop(s);
return s;
}
struct stack_list* stack_new( void )
{
struct stack_list* p = malloc( 1 * sizeof *p );
if( NULL == p )
{
fprintf(stderr, "malloc() in Stack Initialization failed\n");
exit( EXIT_FAILURE ); /* There is no point in going beyond this point */
}
p->head = NULL;
return p;
}
void stack_print( const struct stack_list* s )
{
struct my_stack* p = NULL;
if( NULL == s )
{
printf("Can not print an Empty Stack\n");
}
else
{
for( p = s->head; p; p = p->next ) stack_print_element(p);
}
printf("-------------------------- \n");
}
void stack_print_element(const struct my_stack* s)
{
if( s ) printf("arrc = %s\n", s->arrc);
}
Copyright © 2006, 2007, 2008 Arnuld Uttre, #331/type-2/sector-1, Naya Nangal, Distt. – Ropar, Punjab (INDIA) – 140126
Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this notice, and the copyright notice, are preserved.
Linked List implementation of a Queue in C
May 13, 2009 at 11:51 am | Posted in C++ | 6 CommentsTags: C++, CIA, CIA bogus software, comp.lang.c, Linked List, open source, propriet, proprietary software, Queue, russian pipeline explosion
A Queue is a FIFO based data structure. I tried to create one and got lots of advices and improvements from comp.lang.c folks. I am posting it here, in case someone gets benefit from that. I believe in Open Sharing of source code, it helps the community, it helpes the poor people like me who either did not have money to join some course or did not have enough of experience or a Master’s degree to get a job. Working on an Open Source software greatly improves the ability of the people to write quality code and also (as a side-effect) consumer always gets a robust product, a piece of software that they can trust. I am defnitely sure, you can’t trust a proprietary software, no one knows what its doing on your computer (except of the compnay who created it). MNCs are only intersted in making money and taking control of the market and doing a dishonest business always makes more money than doing an honest business. Having secrets of other corporations delievered to your doorstep always helpes in building a monopoly and I think proprietary software is a brilliant concept to spy on other companies and homes of general public. Never ever forget the Russian gas piple-line scandal. Perhaps reading some news will help.. You can even check amazon. Whether you are a government or an organization or an individual, you can not trust a piece of proprietary software, you don’t know what it does, you will never know.
I have seen people writing poor quality C code for years. They wrote poor C programs when they were 23 ( starting their Master’s degree) and when they were 25 (first day of the job) and now they are 29 and after 4 years of experience they still write poor quality code (Mostly these people are also the ones who have passed their professional degree in first division). Its because they are working in proprietary software based business company because of which they can not share their code. No critics and hence no improvement and in their spare time they never tried to read comp.lang.c archives though they do get time to shake beer glasses with their friends sometime or joke about the habist of their fellow team-mates or their boss or whetever they like but they never get time to read comp.lang.c
. You can always find the original duscussion of my program on Usenet.
/* This Queue implementation of singly linked list in C implements 3
* operations: add, remove and print elements in the list. Well, actually,
* it implements 4 operations, lats one is list_free() but free() should not
* be considered the operation but a mandatory practice like brushing
* teeth every morning, otherwise you will end up loosing some part of
* your body(the software) Its is the modified version of my singly linked
* list suggested by Ben from comp.lang.c . I was using one struct to do
* all the operations but Ben added a 2nd struct to make things easier and
* efficient.
*
* I was always using the strategy of searching through the list to find the
* end and then addd the value there. That way list_add() was O(n). Now I
* am keeping track of tail and always use tail to add to the linked list, so
* the addition is always O(1), only at the cost of one assignment.
*
*
* VERISON 0.5
*
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct my_struct
{
int num;
struct my_struct* next;
};
struct my_list
{
struct my_struct* head;
struct my_struct* tail;
};
struct my_list* list_add_element( struct my_list*, const int);
struct my_list* list_remove_element( struct my_list*);
struct my_list* list_new(void);
struct my_list* list_free( struct my_list* );
void list_print( const struct my_list* );
void list_print_element(const struct my_struct* );
int main(void)
{
struct my_list* mt = NULL;
mt = list_new();
list_add_element(mt, 1);
list_add_element(mt, 2);
list_add_element(mt, 3);
list_add_element(mt, 4);
list_print(mt);
list_remove_element(mt);
list_print(mt);
list_free(mt); /* always remember to free() the malloc()ed memory */
free(mt); /* free() if list is kept separate from free()ing the structure, I think its a good design */
mt = NULL; /* after free() always set that pointer to NULL, C will run havon on you if you try to use a dangling pointer */
list_print(mt);
return 0;
}
/* Will always return the pointer to my_list */
struct my_list* list_add_element(struct my_list* s, const int i)
{
struct my_struct* p = malloc( 1 * sizeof(*p) );
if( NULL == p )
{
fprintf(stderr, "IN %s, %s: malloc() failed\n", __FILE__, "list_add");
return s;
}
p->num = i;
p->next = NULL;
if( NULL == s )
{
printf("Queue not initialized\n");
free(p);
return s;
}
else if( NULL == s->head && NULL == s->tail )
{
/* printf("Empty list, adding p->num: %d\n\n", p->num); */
s->head = s->tail = p;
return s;
}
else if( NULL == s->head || NULL == s->tail )
{
fprintf(stderr, "There is something seriously wrong with your assignment of head/tail to the list\n");
free(p);
return NULL;
}
else
{
/* printf("List not empty, adding element to tail\n"); */
s->tail->next = p;
s->tail = p;
}
return s;
}
/* This is a queue and it is FIFO, so we will always remove the first element */
struct my_list* list_remove_element( struct my_list* s )
{
struct my_struct* h = NULL;
struct my_struct* p = NULL;
if( NULL == s )
{
printf("List is empty\n");
return s;
}
else if( NULL == s->head && NULL == s->tail )
{
printf("Well, List is empty\n");
return s;
}
else if( NULL == s->head || NULL == s->tail )
{
printf("There is something seriously wrong with your list\n");
printf("One of the head/tail is empty while other is not \n");
return s;
}
h = s->head;
p = h->next;
free(h);
s->head = p;
if( NULL == s->head ) s->tail = s->head; /* The element tail was pointing to is free(), so we need an update */
return s;
}
/* ---------------------- small helper fucntions ---------------------------------- */
struct my_list* list_free( struct my_list* s )
{
while( s->head )
{
list_remove_element(s);
}
return s;
}
struct my_list* list_new(void)
{
struct my_list* p = malloc( 1 * sizeof(*p));
if( NULL == p )
{
fprintf(stderr, "LINE: %d, malloc() failed\n", __LINE__);
}
p->head = p->tail = NULL;
return p;
}
void list_print( const struct my_list* ps )
{
struct my_struct* p = NULL;
if( ps )
{
for( p = ps->head; p; p = p->next )
{
list_print_element(p);
}
}
printf("------------------\n");
}
void list_print_element(const struct my_struct* p )
{
if( p )
{
printf("Num = %d\n", p->num);
}
else
{
printf("Can not print NULL struct \n");
}
}
Copyright © 2006, 2007, 2008 Arnuld Uttre, #331/type-2/sector-1, Naya Nangal, Distt. – Ropar, Punjab (INDIA) – 140126
Verbatim copying and distribution of this entire article are permitted worldwide, without royalty, in any medium, provided this notice, and the copyright notice, are preserved.
Blog at WordPress.com. | Theme: Pool by Borja Fernandez.
Entries and comments feeds.