[1] http://bytes.com/topic/c/answers/624119-how-do-you-declare-use-static-constant-array-inside-class
[2] http://www.cplusplus.com/forum/beginner/2052/
HOW DO WE DECLARE AND INITIALIZE CONSTANT CHAR ARRAY? [1]
-----------------------------------------------------------
class Test
{
public:
static const int arr[]= {1,2,3}; // LINE 11
}
You can declare it here, but you can't initialize it here.
Initialize it in a separate definition.
Otherwise, you will get compiling error
"a brace-enclosed initializer is not allowed here before '{' token"
Header file:
class Test
{
public:
static const int arr[];
};
Implementation file in *.cpp:
const int Test::arr[3] = {1,2,3};
iostream linker error is solved by using g++ instead of gcc in makefile.
-----------------------------------------------------------------
Mistake to avoid when using 'inline'
-------------------------------------------------------------
1.Don't put inline in front of class constructor/destructor
2.Don't put inline in front of functions within 'namespace'.
linker error when using static variables in class [2]
--------------------------------------------------------
Tuesday, September 28, 2010
Wednesday, September 15, 2010
Vi / Vim Notes
[1] vim.org tagbar plugin
[2] vimawesome.com vim plugin\
[3] linux.com vim-101-a-beginners-guide-to-vim
[4] derickbailey/2010/04/23/using-vim-as-your-c-code-editor-from-visual-studio/
[5] cscope.sourceforge.net/cscope_vim_tutorial.html
qyang@lubuntu-laptop:~$ tree ~/.vim
/home/qyang/.vim
├── autoload
│ ├── acp.vim
│ └── tagbar.vim
├── doc
│ ├── acp.jax
│ ├── acp.txt
│ ├── tagbar.txt
│ ├── tags
│ └── tags-ja
├── plugin
│ ├── cscope_maps.vim
│ └── tagbar.vim
├── plugins
│ ├── acp.vim
│ ├── cctree.vim
│ ├── ming.vim
│ └── qt.vim
├── README.md
└── syntax
├── python.vim
└── tagbar.vim
ming.vim
set showcmd
set ruler
set nocompatible
set ignorecase smartcase incsearch hlsearch
set nowrap
set smartindent
set backspace=indent,eol,start
function Setcohda(...)
set tabstop=2 shiftwidth=2
set expandtab
endfunction
function Setlinux(...)
set tabstop=8 shiftwidth=8
set noexpandtab
endfunction
command Cohda call Setcohda()
command Linux call Setlinux()
autocmd FileType cpp Cohda
autocmd FileType make set noexpandtab tabstop=8
autocmd FileType python set tabstop=4 shiftwidth=4 noexpandtab
noremap :!make
inoremap :!make
qt.vim
------------------------------------
Generate cscope.out on root directory of source code project, then start vim from that root directory. All symbols index in cscope.out can be used by vim now.
Try below to jump straight to the file including 'main' symbol
Insert following code into makefile to generate cscope.out via make.
DISPLAY TAB
---------------------
Not quite work correctly to show all tabs
:SeeTab vim.wikia.com
OPEN MULTIPLE FILES FROM CMD LINE
-------------------------
TURN ON LINE NUMBER
------------------------
:set number
REPLACE A STRING
-------------------
:1,$s/word1/word2/gc IN A WHOLE FILE
:n1,n2s/word1/word2/gc IN BETWEEN LINE 'n1' and 'n2', special character use '\' prefix. (e.g.,:1,$s/word\[/word1\[/gc, replace 'word[' with 'word1[' )
COMMAND MODE
---------------------
'g0' -- go zero, go to head of line;
'g$' -- go to end of line;
'G' -- go to end of this file;
'H' -- go to top of screen;
'M' -- go to middle of screen;
'L' -- go to bottom of screen;
'nG' -- go to line number 'n'
'/word' -- search a string 'word' forward;
'?word' -- search a string 'word' backward;
'nyy' -- yank/copy n lines after cursor;
'p' -- paste yanked contens one line below cursor;
'dd' -- delete current line;
'nd' -- delete n lines after cursor;
DELETE/COPY(YANK) A BLOCK OF TEXT
----------------------------
The ‘mark command can be very useful when deleting a long series of lines.To
delete a long series of lines, follow these steps:
1. Move the cursor to the beginning of the text you want to delete.
2. Mark it using the command ma. (This marks it with mark a.)
3. Go to the end of the text to be removed. Delete to mark a using the command
d’a.
Note:There is nothing special about using the a mark. Any mark from a to z
may be used.
BACK TO PREVIOUSLY VISITED LOCATION previous view
-----------------------------
Ctrl + O
Ctrl + I (tab)
Jumping_to_previously_visited_locations
JUMP TO SYMBOL DEFINITION when ctags/cscope enabled
------------------------------
Ctrl + ]
Ctrl + T
A 05 Vi Exercise
===============================
[1] http://stackoverflow.com/questions/1737163/traversing-text-in-insert-mode
Insert mode and navigation mode switch
----------------------------------------
ESC or Ctrl+[
Navigation Fast
--------------------
15 + h go backward 15 characters
5 + j go forward 5 lines
Ctrl+o + 2 + b navigate two words back without leaving insert mode
Ctrl+o will give you chance to run one vi command at navigation
mode, then return to insert mode automatically.
'+. back to previous editing place after navigation
Type 20 '-' delete backword 9 '-'
----------------------------------------
20 + i + - + ESC
9 + X
'20' set number of execute times
'i' into insert mode
'-' letter or words you want to repeat
'ESC' back to navigation mode will display all insert letters.
'9' set number of exectue times
'X' delete backward, 'x' delete forward
Paste from clip board
-----------------------------------
"+p
" use register
+ clipboard register index
p paste shortcut key
Corret Typo
----------------------
accifently
FfrdA will correct the word from accifently to accidently
'F' find backward 'f' find forward
'f' find letter 'f'
'r' replace current cursor
'd' type correct letter 'd'
'A' back to original edit place
Rewrite word
--------------------
you accidentlly typed
you intentially typed
you intertially typed
ESC + 2 + b + c + w intentially + ESC + A
Write words in multiple lines
--------------------
[2] http://vim.wikia.com/wiki/Inserting_text_in_multiple_lines
hello
hello
hello
hel:added:loappend
hel:added:loappend
hel:added:loappend
hllo hello append
hllo hello append
hllo hello append
Ctrl+v + navigate coursor to 'l' + j + j + j + I + :added: + ESC
Ctrl+v + navigate coursor to 'o' + l + A + Ctrl+R + "
Ctrl+v + select block you want to delete + d
'Ctrl+v' visual block mode.
'I' insert before current cursor in visual block mode.
'A' append after current cursor in visual block mode.
'Ctrl + R + "' past yank register in insert mode
'Ctrl + R + +' past clipboard insert mode.
[2] vimawesome.com vim plugin\
[3] linux.com vim-101-a-beginners-guide-to-vim
[4] derickbailey/2010/04/23/using-vim-as-your-c-code-editor-from-visual-studio/
[5] cscope.sourceforge.net/cscope_vim_tutorial.html
qyang@lubuntu-laptop:~$ tree ~/.vim
/home/qyang/.vim
├── autoload
│ ├── acp.vim
│ └── tagbar.vim
├── doc
│ ├── acp.jax
│ ├── acp.txt
│ ├── tagbar.txt
│ ├── tags
│ └── tags-ja
├── plugin
│ ├── cscope_maps.vim
│ └── tagbar.vim
├── plugins
│ ├── acp.vim
│ ├── cctree.vim
│ ├── ming.vim
│ └── qt.vim
├── README.md
└── syntax
├── python.vim
└── tagbar.vim
ming.vim
qt.vim
------------------------------------
: colorscheme morning
: syntax on
: autocmd FileType * set formatoptions=tcql nocindent comments&
: autocmd InsertEnter * colorscheme blue
: autocmd InsertLeave * colorscheme morning
: set autowrite
: ab #d #define
: ab #i #include
: ab #b /********************************************************
: ab #e ^H^H********************************************************/
: ab #l /*------------------------------------------------------*/
: set sw=4
: set notextmode
: set notextauto
: set hlsearch
: set incsearch
: set textwidth=150
: au BufWinEnter * let w:m1=matchadd('Search','\%<151v .="">77v', -1)
: au BufWinEnter * let w:m2=matchadd('ErrorMsg', '\%>150v.\+', -1)
: autocmd FileType c,cpp set formatoptions=croql cindent comments=sr: /*,mb: *.ex: */,: //
: set nowrap
: match ErrorMsg '\%>80v.\+'
: set expandtab
: set shiftwidth=2
: set softtabstop=2
: map : s/^/\/\//
: map : s/^\/\///
: set smartcase
: set ic 151v>
: nmap :TagbarToggle func! DeleteTrailingWS() exe "normal mz" %s/\s\+$//ge exe "normal `z" endfunc autocmd BufWrite *.py : call DeleteTrailingWS()
Generate cscope.out on root directory of source code project, then start vim from that root directory. All symbols index in cscope.out can be used by vim now.
Try below to jump straight to the file including 'main' symbol
$vi -t main
Insert following code into makefile to generate cscope.out via make.
$make cscope -f MakefileName
# Make software
#
# Generate csope files
cscope: cscope.out
cscope.out: cscope.files
@cscope -R -b -i $<
cscope.files:
@find am335x -name "*.[ch]" -not -path "*/bootloader/*" > $@ && \
find libs -name "*.[ch]" -not -path "*/kissfft/*" >> $@ && \
find am335x -name "*.cpp" -o -name "*.h" -not -path "*/bootloader/*" >>
find rtos -name "*.c" -o -name "*.h" -o -name "*.cpp" >> $@
clean:
@rm cscope.*
DISPLAY TAB
---------------------
Not quite work correctly to show all tabs
:SeeTab vim.wikia.com
OPEN MULTIPLE FILES FROM CMD LINE
-------------------------
qyang@lubuntu-laptop:~/Git_Local_Sandbox/PcapPlot$ vi -g -p *.sh *.py 12 files to edit
TURN ON LINE NUMBER
------------------------
:set number
REPLACE A STRING
-------------------
:1,$s/word1/word2/gc IN A WHOLE FILE
:n1,n2s/word1/word2/gc IN BETWEEN LINE 'n1' and 'n2', special character use '\' prefix. (e.g.,:1,$s/word\[/word1\[/gc, replace 'word[' with 'word1[' )
COMMAND MODE
---------------------
'g0' -- go zero, go to head of line;
'g$' -- go to end of line;
'G' -- go to end of this file;
'H' -- go to top of screen;
'M' -- go to middle of screen;
'L' -- go to bottom of screen;
'nG' -- go to line number 'n'
'/word' -- search a string 'word' forward;
'?word' -- search a string 'word' backward;
'nyy' -- yank/copy n lines after cursor;
'p' -- paste yanked contens one line below cursor;
'dd' -- delete current line;
'nd' -- delete n lines after cursor;
DELETE/COPY(YANK) A BLOCK OF TEXT
----------------------------
The ‘mark command can be very useful when deleting a long series of lines.To
delete a long series of lines, follow these steps:
1. Move the cursor to the beginning of the text you want to delete.
2. Mark it using the command ma. (This marks it with mark a.)
3. Go to the end of the text to be removed. Delete to mark a using the command
d’a.
Note:There is nothing special about using the a mark. Any mark from a to z
may be used.
BACK TO PREVIOUSLY VISITED LOCATION previous view
-----------------------------
Ctrl + O
Ctrl + I (tab)
Jumping_to_previously_visited_locations
JUMP TO SYMBOL DEFINITION when ctags/cscope enabled
------------------------------
Ctrl + ]
Ctrl + T
A 05 Vi Exercise
===============================
[1] http://stackoverflow.com/questions/1737163/traversing-text-in-insert-mode
Insert mode and navigation mode switch
----------------------------------------
ESC or Ctrl+[
Navigation Fast
--------------------
15 + h go backward 15 characters
5 + j go forward 5 lines
Ctrl+o + 2 + b navigate two words back without leaving insert mode
Ctrl+o will give you chance to run one vi command at navigation
mode, then return to insert mode automatically.
'+. back to previous editing place after navigation
Type 20 '-' delete backword 9 '-'
----------------------------------------
20 + i + - + ESC
9 + X
'20' set number of execute times
'i' into insert mode
'-' letter or words you want to repeat
'ESC' back to navigation mode will display all insert letters.
'9' set number of exectue times
'X' delete backward, 'x' delete forward
Paste from clip board
-----------------------------------
"+p
" use register
+ clipboard register index
p paste shortcut key
Corret Typo
----------------------
accifently
FfrdA will correct the word from accifently to accidently
'F' find backward 'f' find forward
'f' find letter 'f'
'r' replace current cursor
'd' type correct letter 'd'
'A' back to original edit place
Rewrite word
--------------------
you accidentlly typed
you intentially typed
you intertially typed
ESC + 2 + b + c + w intentially + ESC + A
Write words in multiple lines
--------------------
[2] http://vim.wikia.com/wiki/Inserting_text_in_multiple_lines
hello
hello
hello
hel:added:loappend
hel:added:loappend
hel:added:loappend
hllo hello append
hllo hello append
hllo hello append
Ctrl+v + navigate coursor to 'l' + j + j + j + I + :added: + ESC
Ctrl+v + navigate coursor to 'o' + l + A + Ctrl+R + "
Ctrl+v + select block you want to delete + d
'Ctrl+v' visual block mode.
'I' insert before current cursor in visual block mode.
'A' append after current cursor in visual block mode.
'Ctrl + R + "' past yank register in insert mode
'Ctrl + R + +' past clipboard insert mode.
Gcc Command line based quick compiling
task2.cpp
#include
using namespace std;
int main()
{
char line[100];
cin >> line;
cout << "input data stream is:\n"<
}
[q.yang@localhost Sandbox]$ g++ task2.cpp -o task2
[q.yang@localhost Sandbox]$ ll
total 28
-rwxr-xr-x 1 q.yang developer 6392 2010-09-16 12:44 task2
-rw-r--r-- 1 q.yang developer 168 2010-09-16 12:31 task2.cpp
-rw-r--r-- 1 q.yang developer 1976 2010-09-16 12:34 task2.o
[q.yang@localhost Sandbox]$ ./task2
hello
input data stream is:
hello
Added new user account and set up VNC.
ADD USER THAT BELONG TO A GROUP
--------------------------------------
[root@localhost q.yang]# useradd -g developer guest
ADD USER
-------------------
#useradd john
MODIFY USER ACCOUNT
------------------
#usermod
SET PASSWORD for NEW USER
-----------------------------
#passwd john
[q.yang@localhost ~]$ ll /home/
total 20
drwx------ 4 guest developer 4096 2010-09-16 11:14 guest
drwx------ 2 root root 4096 2010-07-20 07:29 lost+found
drwx------ 38 q.yang q.yang 4096 2010-09-16 11:14 q.yang
CHANGE GROUP OWNERSHIP FOR ALL FILES IN PATH ./
--------------------------------------------------
[q.yang@localhost ~]$ chgrp -Rv developer ./
--------------------------------------
[root@localhost q.yang]# useradd -g developer guest
ADD USER
-------------------
#useradd john
MODIFY USER ACCOUNT
------------------
#usermod
SET PASSWORD for NEW USER
-----------------------------
#passwd john
[q.yang@localhost ~]$ ll /home/
total 20
drwx------ 4 guest developer 4096 2010-09-16 11:14 guest
drwx------ 2 root root 4096 2010-07-20 07:29 lost+found
drwx------ 38 q.yang q.yang 4096 2010-09-16 11:14 q.yang
CHANGE GROUP OWNERSHIP FOR ALL FILES IN PATH ./
--------------------------------------------------
[q.yang@localhost ~]$ chgrp -Rv developer ./
Wednesday, August 18, 2010
Static function in C
From: http://www.lix.polytechnique.fr/~liberti/public/computing/prog/c/C/SYNTAX/static.htm
static functions are functions that are only visable to other functions in the same file. Consider the following code.
static functions are functions that are only visable to other functions in the same file. Consider the following code.
FW: Top Ten Errors Java Programmers Make
From: http://www.javacoffeebreak.com/articles/toptenerrors.html
Top Ten Errors Java Programmers Make
(How to spot them. How to fix/prevent them.)
By David Reilly
Whether you program regularly in Java, and know it like the back of your hand, or whether you're new to the language or a casual programmer, you'll make mistakes. It's natural, it's human, and guess what? You'll more than likely make the same mistakes that others do, over and over again. Here's my top ten list of errors that we all seem to make at one time or another, how to spot them, and how to fix them.
10. Accessing non-static member variables from static methods (such as main)
Many programmers, particularly when first introduced to Java, have problems with accessing member variables from their main method. The method signature for main is marked static - meaning that we don't need to create an instance of the class to invoke the main method. For example, a Java Virtual Machine (JVM) could call the class MyApplication like this :-
MyApplication.main ( command_line_args );
This means, however, that there isn't an instance of MyApplication - it doesn't have any member variables to access! Take for example the following application, which will generate a compiler error message.
public class StaticDemo
{
public String my_member_variable = "somedata";
public static void main (String args[])
{
// Access a non-static member from static method
System.out.println ("This generates a compiler error" +
my_member_variable );
}
}
If you want to access its member variables from a non-static method (like main), you must create an instance of the object. Here's a simple example of how to correctly write code to access non-static member variables, by first creating an instance of the object.
public class NonStaticDemo
{
public String my_member_variable = "somedata";
public static void main (String args[])
{
NonStaticDemo demo = new NonStaticDemo();
// Access member variable of demo
System.out.println ("This WON'T generate an error" +
demo.my_member_variable );
}
}
9. Mistyping the name of a method when overriding
Overriding allows programmers to replace a method's implementation with new code. Overriding is a handy feature, and most OO programmers make heavy use of it. If you use the AWT 1.1 event handling model, you'll often override listener implementations to provide custom functionality. One easy trap to fall into with overriding, is to mistype the method name. If you mistype the name, you're no longer overriding a method - you're creating an entirely new method, but with the same parameter and return type.
public class MyWindowListener extends WindowAdapter {
// This should be WindowClosed
public void WindowClose(WindowEvent e) {
// Exit when user closes window
System.exit(0);
}
});
Compilers won't pick up on this one, and the problem can be quite frustrating to detect. In the past, I've looked at a method, believed that it was being called, and taken ages to spot the problem. The symptom of this error will be that your code isn't being called, or you think the method has skipped over its code. The only way to ever be certain is to add a println statement, to record a message in a log file, or to use good trace debugger (like Visual J++ or Borland JBuilder) and step through line by line. If your method still isn't being called, then it's likely you've mistyped the name.
8. Comparison assignment ( = rather than == )
This is an easy error to make. If you're used other languages before, such as Pascal, you'll realize just how poor a choice this was by the language's designers. In Pascal, for example, we use the := operator for assignment, and leave = for comparison. This looks like a throwback to C/C++, from which Java draws its roots.
Fortunately, even if you don't spot this one by looking at code on the screen, your compiler will. Most commonly, it will report an error message like this : "Can't convert xxx to boolean", where xxx is a Java type that you're assigning instead of comparing.
7. Comparing two objects ( == instead of .equals)
When we use the == operator, we are actually comparing two object references, to see if they point to the same object. We cannot compare, for example, two strings for equality, using the == operator. We must instead use the .equals method, which is a method inherited by all classes from java.lang.Object.
Here's the correct way to compare two strings.
String abc = "abc"; String def = "def";
// Bad way
if ( (abc + def) == "abcdef" )
{
......
}
// Good way
if ( (abc + def).equals("abcdef") )
{
.....
}
6. Confusion over passing by value, and passing by reference
This can be a frustrating problem to diagnose, because when you look at the code, you might be sure that its passing by reference, but find that its actually being passed by value. Java uses both, so you need to understand when you're passing by value, and when you're passing by reference.
When you pass a primitive data type, such as a char, int, float, or double, to a function then you are passing by value. That means that a copy of the data type is duplicated, and passed to the function. If the function chooses to modify that value, it will be modifying the copy only. Once the function finishes, and control is returned to the returning function, the "real" variable will be untouched, and no changes will have been saved. If you need to modify a primitive data type, make it a return value for a function, or wrap it inside an object.
When you pass a Java object, such as an array, a vector, or a string, to a function then you are passing by reference. Yes - a String is actually an object, not a primitive data type. So that means that if you pass an object to a function, you are passing a reference to it, not a duplicate. Any changes you make to the object's member variables will be permanent - which can be either good or bad, depending on whether this was what you intended.
On a side note, since String contains no methods to modify its contents, you might as well be passing by value.
5. Writing blank exception handlers
I know it's very tempting to write blank exception handlers, and to just ignore errors. But if you run into problems, and haven't written any error messages, it becomes almost impossible to find out the cause of the error. Even the simplest exception handler can be of benefit. For example, put a try { .. } catch Exception around your code, to catch ANY type of exception, and print out the message. You don't need to write a custom handler for every exception (though this is still good programming practice). Don't ever leave it blank, or you won't know what's happening.
For example
public static void main(String args[])
{
try {
// Your code goes here..
}
catch (Exception e)
{
System.out.println ("Err - " + e );
}
}
4. Forgetting that Java is zero-indexed
If you've come from a C/C++ background, you may not find this quite as much a problem as those who have used other languages. In Java, arrays are zero-indexed, meaning that the first element's index is actually 0. Confused? Let's look at a quick example.
// Create an array of three strings
String[] strArray = new String[3];
// First element's index is actually 0
strArray[0] = "First string";
// Second element's index is actually 1
strArray[1] = "Second string";
// Final element's index is actually 2
strArray[2] = "Third and final string";
In this example, we have an array of three strings, but to access elements of the array we actually subtract one. Now, if we were to try and access strArray[3], we'd be accessing the fourth element. This will case an ArrayOutOfBoundsException to be thrown - the most obvious sign of forgetting the zero-indexing rule.
Other areas where zero-indexing can get you into trouble is with strings. Suppose you wanted to get a character at a particular offset within a string. Using the String.charAt(int) function you can look this information up - but under Java, the String class is also zero-indexed. That means than the first character is at offset 0, and second at offset 1. You can run into some very frustrating problems unless you are aware of this - particularly if you write applications with heavy string processing. You can be working on the wrong character, and also throw exceptions at run-time. Just like the ArrayOutOfBoundsException, there is a string equivalent. Accessing beyond the bounds of a String will cause a StringIndexOutOfBoundsException to be thrown, as demonstrated by this example.
public class StrDemo
{
public static void main (String args[])
{
String abc = "abc";
System.out.println ("Char at offset 0 : " + abc.charAt(0) );
System.out.println ("Char at offset 1 : " + abc.charAt(1) );
System.out.println ("Char at offset 2 : " + abc.charAt(2) );
// This line should throw a StringIndexOutOfBoundsException
System.out.println ("Char at offset 3 : " + abc.charAt(3) );
}
}
Note too, that zero-indexing doesn't just apply to arrays, or to Strings. Other parts of Java are also indexed, but not always consistently. The java.util.Date, and java.util.Calendar classes start their months with 0, but days start normally with 1. This problem is demonstrated by the following application.
import java.util.Date;
import java.util.Calendar;
public class ZeroIndexedDate
{
public static void main (String args[])
{
// Get today's date
Date today = new Date();
// Print return value of getMonth
System.out.println ("Date.getMonth() returns : " +
today.getMonth());
// Get today's date using a Calendar
Calendar rightNow = Calendar.getInstance();
// Print return value of get ( Calendar.MONTH )
System.out.println ("Calendar.get (month) returns : " +
rightNow.get ( Calendar.MONTH ));
}
}
Zero-indexing is only a problem if you don't realize that its occurring. If you think you're running into a problem, always consult your API documentation.
3. Preventing concurrent access to shared variables by threads
When writing multi-threaded applications, many programmers (myself included) often cut corners, and leave their applications and applets vulnerable to thread conflicts. When two or more threads access the same data concurrently, there exists the possibility (and Murphy's law holding, the probability) that two threads will access or modify the same data at the same time. Don't be fooled into thinking that such problems won't occur on single-threaded processors. While accessing some data (performing a read), your thread may be suspended, and another thread scheduled. It writes its data, which is then overwritten when the first thread makes its changes.
Such problems are not just limited to multi-threaded applications or applets. If you write Java APIs, or JavaBeans, then your code may not be thread-safe. Even if you never write a single application that uses threads, people that use your code WILL. For the sanity of others, if not yourself, you should always take precautions to prevent concurrent access to shared data.
How can this problem be solved? The simplest method is to make your variables private (but you do that already, right?) and to use synchronized accessor methods. Accessor methods allow access to private member variables, but in a controlled manner. Take the following accessor methods, which provide a safe way to change the value of a counter.
public class MyCounter
{
private int count = 0; // count starts at zero
public synchronized void setCount(int amount)
{
count = amount;
}
public synchronized int getCount()
{
return count;
}
}
2. Capitalization errors
This is one of the most frequent errors that we all make. It's so simple to do, and sometimes one can look at an uncapitalized variable or method and still not spot the problem. I myself have often been puzzled by these errors, because I recognize that the method or variable does exist, but don't spot the lack of capitalization.
While there's no silver bullet for detecting this error, you can easily train yourself to make less of them. There's a very simple trick you can learn :-
* all methods and member variables in the Java API begin with lowercase letters
* all methods and member variables use capitalization where a new word begins e.g - getDoubleValue()
If you use this pattern for all of your member variables and classes, and then make a conscious effort to get it right, you can gradually reduce the number of mistakes you'll make. It may take a while, but it can save some serious head scratching in the future.
(drum roll)
And the number one error that Java programmers make !!!!!
1. Null pointers!
Null pointers are one of the most common errors that Java programmers make. Compilers can't check this one for you - it will only surface at runtime, and if you don't discover it, your users certainly will.
When an attempt to access an object is made, and the reference to that object is null, a NullPointerException will be thrown. The cause of null pointers can be varied, but generally it means that either you haven't initialized an object, or you haven't checked the return value of a function.
Many functions return null to indicate an error condition - but unless you check your return values, you'll never know what's happening. Since the cause is an error condition, normal testing may not pick it up - which means that your users will end up discovering the problem for you. If the API function indicates that null may be returned, be sure to check this before using the object reference!
Another cause is where your initialization has been sloppy, or where it is conditional. For example, examine the following code, and see if you can spot the problem.
public static void main(String args[])
{
// Accept up to 3 parameters
String[] list = new String[3];
int index = 0;
while ( (index < args.length) && ( index < 3 ) )
{
list[index++] = args[index];
}
// Check all the parameters
for (int i = 0; i < list.length; i++)
{
if (list[i].equals "-help")
{
// .........
}
else
if (list[i].equals "-cp")
{
// .........
}
// else .....
}
}
This code (while a contrived example), shows a common mistake. Under some circumstances, where the user enters three or more parameters, the code will run fine. If no parameters are entered, you'll get a NullPointerException at runtime. Sometimes your variables (the array of strings) will be initialized, and other times they won't. One easy solution is to check BEFORE you attempt to access a variable in an array that it is not equal to null.
Summary
These errors represent but some of the many that we all make. Though it is impossible to completely eliminate errors from the coding process, with care and practice you can avoid repeating the same ones. Rest assured, however, that all Java programmers encounter the same sorts of problems. It's comforting to know, that while you work late into the night tracking down an error, someone, somewhere, sometime, will make the same mistake!
We'd like to thank the readers of the comp.lang.java.programmer newsgroup for their suggestions for the top ten. Regrettably, due to the number of submissions, not every error could be featured - but we think this "Top Ten" list represents the most popular and frequent errors people make.
Top Ten Errors Java Programmers Make
(How to spot them. How to fix/prevent them.)
By David Reilly
Whether you program regularly in Java, and know it like the back of your hand, or whether you're new to the language or a casual programmer, you'll make mistakes. It's natural, it's human, and guess what? You'll more than likely make the same mistakes that others do, over and over again. Here's my top ten list of errors that we all seem to make at one time or another, how to spot them, and how to fix them.
10. Accessing non-static member variables from static methods (such as main)
Many programmers, particularly when first introduced to Java, have problems with accessing member variables from their main method. The method signature for main is marked static - meaning that we don't need to create an instance of the class to invoke the main method. For example, a Java Virtual Machine (JVM) could call the class MyApplication like this :-
MyApplication.main ( command_line_args );
This means, however, that there isn't an instance of MyApplication - it doesn't have any member variables to access! Take for example the following application, which will generate a compiler error message.
public class StaticDemo
{
public String my_member_variable = "somedata";
public static void main (String args[])
{
// Access a non-static member from static method
System.out.println ("This generates a compiler error" +
my_member_variable );
}
}
If you want to access its member variables from a non-static method (like main), you must create an instance of the object. Here's a simple example of how to correctly write code to access non-static member variables, by first creating an instance of the object.
public class NonStaticDemo
{
public String my_member_variable = "somedata";
public static void main (String args[])
{
NonStaticDemo demo = new NonStaticDemo();
// Access member variable of demo
System.out.println ("This WON'T generate an error" +
demo.my_member_variable );
}
}
9. Mistyping the name of a method when overriding
Overriding allows programmers to replace a method's implementation with new code. Overriding is a handy feature, and most OO programmers make heavy use of it. If you use the AWT 1.1 event handling model, you'll often override listener implementations to provide custom functionality. One easy trap to fall into with overriding, is to mistype the method name. If you mistype the name, you're no longer overriding a method - you're creating an entirely new method, but with the same parameter and return type.
public class MyWindowListener extends WindowAdapter {
// This should be WindowClosed
public void WindowClose(WindowEvent e) {
// Exit when user closes window
System.exit(0);
}
});
Compilers won't pick up on this one, and the problem can be quite frustrating to detect. In the past, I've looked at a method, believed that it was being called, and taken ages to spot the problem. The symptom of this error will be that your code isn't being called, or you think the method has skipped over its code. The only way to ever be certain is to add a println statement, to record a message in a log file, or to use good trace debugger (like Visual J++ or Borland JBuilder) and step through line by line. If your method still isn't being called, then it's likely you've mistyped the name.
8. Comparison assignment ( = rather than == )
This is an easy error to make. If you're used other languages before, such as Pascal, you'll realize just how poor a choice this was by the language's designers. In Pascal, for example, we use the := operator for assignment, and leave = for comparison. This looks like a throwback to C/C++, from which Java draws its roots.
Fortunately, even if you don't spot this one by looking at code on the screen, your compiler will. Most commonly, it will report an error message like this : "Can't convert xxx to boolean", where xxx is a Java type that you're assigning instead of comparing.
7. Comparing two objects ( == instead of .equals)
When we use the == operator, we are actually comparing two object references, to see if they point to the same object. We cannot compare, for example, two strings for equality, using the == operator. We must instead use the .equals method, which is a method inherited by all classes from java.lang.Object.
Here's the correct way to compare two strings.
String abc = "abc"; String def = "def";
// Bad way
if ( (abc + def) == "abcdef" )
{
......
}
// Good way
if ( (abc + def).equals("abcdef") )
{
.....
}
6. Confusion over passing by value, and passing by reference
This can be a frustrating problem to diagnose, because when you look at the code, you might be sure that its passing by reference, but find that its actually being passed by value. Java uses both, so you need to understand when you're passing by value, and when you're passing by reference.
When you pass a primitive data type, such as a char, int, float, or double, to a function then you are passing by value. That means that a copy of the data type is duplicated, and passed to the function. If the function chooses to modify that value, it will be modifying the copy only. Once the function finishes, and control is returned to the returning function, the "real" variable will be untouched, and no changes will have been saved. If you need to modify a primitive data type, make it a return value for a function, or wrap it inside an object.
When you pass a Java object, such as an array, a vector, or a string, to a function then you are passing by reference. Yes - a String is actually an object, not a primitive data type. So that means that if you pass an object to a function, you are passing a reference to it, not a duplicate. Any changes you make to the object's member variables will be permanent - which can be either good or bad, depending on whether this was what you intended.
On a side note, since String contains no methods to modify its contents, you might as well be passing by value.
5. Writing blank exception handlers
I know it's very tempting to write blank exception handlers, and to just ignore errors. But if you run into problems, and haven't written any error messages, it becomes almost impossible to find out the cause of the error. Even the simplest exception handler can be of benefit. For example, put a try { .. } catch Exception around your code, to catch ANY type of exception, and print out the message. You don't need to write a custom handler for every exception (though this is still good programming practice). Don't ever leave it blank, or you won't know what's happening.
For example
public static void main(String args[])
{
try {
// Your code goes here..
}
catch (Exception e)
{
System.out.println ("Err - " + e );
}
}
4. Forgetting that Java is zero-indexed
If you've come from a C/C++ background, you may not find this quite as much a problem as those who have used other languages. In Java, arrays are zero-indexed, meaning that the first element's index is actually 0. Confused? Let's look at a quick example.
// Create an array of three strings
String[] strArray = new String[3];
// First element's index is actually 0
strArray[0] = "First string";
// Second element's index is actually 1
strArray[1] = "Second string";
// Final element's index is actually 2
strArray[2] = "Third and final string";
In this example, we have an array of three strings, but to access elements of the array we actually subtract one. Now, if we were to try and access strArray[3], we'd be accessing the fourth element. This will case an ArrayOutOfBoundsException to be thrown - the most obvious sign of forgetting the zero-indexing rule.
Other areas where zero-indexing can get you into trouble is with strings. Suppose you wanted to get a character at a particular offset within a string. Using the String.charAt(int) function you can look this information up - but under Java, the String class is also zero-indexed. That means than the first character is at offset 0, and second at offset 1. You can run into some very frustrating problems unless you are aware of this - particularly if you write applications with heavy string processing. You can be working on the wrong character, and also throw exceptions at run-time. Just like the ArrayOutOfBoundsException, there is a string equivalent. Accessing beyond the bounds of a String will cause a StringIndexOutOfBoundsException to be thrown, as demonstrated by this example.
public class StrDemo
{
public static void main (String args[])
{
String abc = "abc";
System.out.println ("Char at offset 0 : " + abc.charAt(0) );
System.out.println ("Char at offset 1 : " + abc.charAt(1) );
System.out.println ("Char at offset 2 : " + abc.charAt(2) );
// This line should throw a StringIndexOutOfBoundsException
System.out.println ("Char at offset 3 : " + abc.charAt(3) );
}
}
Note too, that zero-indexing doesn't just apply to arrays, or to Strings. Other parts of Java are also indexed, but not always consistently. The java.util.Date, and java.util.Calendar classes start their months with 0, but days start normally with 1. This problem is demonstrated by the following application.
import java.util.Date;
import java.util.Calendar;
public class ZeroIndexedDate
{
public static void main (String args[])
{
// Get today's date
Date today = new Date();
// Print return value of getMonth
System.out.println ("Date.getMonth() returns : " +
today.getMonth());
// Get today's date using a Calendar
Calendar rightNow = Calendar.getInstance();
// Print return value of get ( Calendar.MONTH )
System.out.println ("Calendar.get (month) returns : " +
rightNow.get ( Calendar.MONTH ));
}
}
Zero-indexing is only a problem if you don't realize that its occurring. If you think you're running into a problem, always consult your API documentation.
3. Preventing concurrent access to shared variables by threads
When writing multi-threaded applications, many programmers (myself included) often cut corners, and leave their applications and applets vulnerable to thread conflicts. When two or more threads access the same data concurrently, there exists the possibility (and Murphy's law holding, the probability) that two threads will access or modify the same data at the same time. Don't be fooled into thinking that such problems won't occur on single-threaded processors. While accessing some data (performing a read), your thread may be suspended, and another thread scheduled. It writes its data, which is then overwritten when the first thread makes its changes.
Such problems are not just limited to multi-threaded applications or applets. If you write Java APIs, or JavaBeans, then your code may not be thread-safe. Even if you never write a single application that uses threads, people that use your code WILL. For the sanity of others, if not yourself, you should always take precautions to prevent concurrent access to shared data.
How can this problem be solved? The simplest method is to make your variables private (but you do that already, right?) and to use synchronized accessor methods. Accessor methods allow access to private member variables, but in a controlled manner. Take the following accessor methods, which provide a safe way to change the value of a counter.
public class MyCounter
{
private int count = 0; // count starts at zero
public synchronized void setCount(int amount)
{
count = amount;
}
public synchronized int getCount()
{
return count;
}
}
2. Capitalization errors
This is one of the most frequent errors that we all make. It's so simple to do, and sometimes one can look at an uncapitalized variable or method and still not spot the problem. I myself have often been puzzled by these errors, because I recognize that the method or variable does exist, but don't spot the lack of capitalization.
While there's no silver bullet for detecting this error, you can easily train yourself to make less of them. There's a very simple trick you can learn :-
* all methods and member variables in the Java API begin with lowercase letters
* all methods and member variables use capitalization where a new word begins e.g - getDoubleValue()
If you use this pattern for all of your member variables and classes, and then make a conscious effort to get it right, you can gradually reduce the number of mistakes you'll make. It may take a while, but it can save some serious head scratching in the future.
(drum roll)
And the number one error that Java programmers make !!!!!
1. Null pointers!
Null pointers are one of the most common errors that Java programmers make. Compilers can't check this one for you - it will only surface at runtime, and if you don't discover it, your users certainly will.
When an attempt to access an object is made, and the reference to that object is null, a NullPointerException will be thrown. The cause of null pointers can be varied, but generally it means that either you haven't initialized an object, or you haven't checked the return value of a function.
Many functions return null to indicate an error condition - but unless you check your return values, you'll never know what's happening. Since the cause is an error condition, normal testing may not pick it up - which means that your users will end up discovering the problem for you. If the API function indicates that null may be returned, be sure to check this before using the object reference!
Another cause is where your initialization has been sloppy, or where it is conditional. For example, examine the following code, and see if you can spot the problem.
public static void main(String args[])
{
// Accept up to 3 parameters
String[] list = new String[3];
int index = 0;
while ( (index < args.length) && ( index < 3 ) )
{
list[index++] = args[index];
}
// Check all the parameters
for (int i = 0; i < list.length; i++)
{
if (list[i].equals "-help")
{
// .........
}
else
if (list[i].equals "-cp")
{
// .........
}
// else .....
}
}
This code (while a contrived example), shows a common mistake. Under some circumstances, where the user enters three or more parameters, the code will run fine. If no parameters are entered, you'll get a NullPointerException at runtime. Sometimes your variables (the array of strings) will be initialized, and other times they won't. One easy solution is to check BEFORE you attempt to access a variable in an array that it is not equal to null.
Summary
These errors represent but some of the many that we all make. Though it is impossible to completely eliminate errors from the coding process, with care and practice you can avoid repeating the same ones. Rest assured, however, that all Java programmers encounter the same sorts of problems. It's comforting to know, that while you work late into the night tracking down an error, someone, somewhere, sometime, will make the same mistake!
We'd like to thank the readers of the comp.lang.java.programmer newsgroup for their suggestions for the top ten. Regrettably, due to the number of submissions, not every error could be featured - but we think this "Top Ten" list represents the most popular and frequent errors people make.
Thursday, July 29, 2010
Task synchronization in Linux
[1] http://docs.blackfin.uclinux.org/doku.php?id=linux-kernel:programming
[2] Understanding the Linux Kernel, 3rd Edition By Daniel P. Bovet, Marco Cesati Publisher: O'Reilly Pub Date: November 2005 ISBN: 0-596-00565-2 Pages: 942
[3] http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/apis/apiexusmem.htm
KERNEL THREAD
--------------------
The only difference between a kernel thread and a user thread is the fact that the kernel thread has no user task memory mapping. Like other user processes it shares the kernel address space but the thread operates only in kernel space with kernel privilages.
A thread is normally designed as a continous loop that calls some wait or scheduling function to stop it consuming 100% of the CPU.
Process creat thread
SPIN LOCK
----------------------------
As a general rule, kernel preemption is disabled in every critical region protected by spin locks. In the case of a uniprocessor system, the locks themselves are useless, and the spin lock primitives just disable or enable the kernel preemption. Please notice that kernel preemption is still enabled during the busy wait phase, thus a process waiting for a spin lock to be released could be replaced by a higher priority process. [2] 5.2.4
SEMAPHORES
-------------------------
Why need semaphore?
In general, safe access to a global variable is ensured by using atomic operations . In the previous example, data corruption is not possible if the two control paths read and decrease V with a single, noninterruptible operation. However, kernels contain many data structures that cannot be accessed with a single operation.
The down( ) method decreases the value of the semaphore. If the new value is less than 0, the method adds the running process to the semaphore list and then blocks (i.e., invokes the scheduler). The up( ) method increases the value of the semaphore and, if its new value is greater than or equal to 0, reactivates one or more processes in the semaphore list. [2] 1.6.5
Each data structure to be protected has its own semaphore, which is initialized to 1. When a kernel control path wishes to access the data structure, it executes the down( ) method on the proper semaphore. If the value of the new semaphore isn't negative, access to the data structure is granted. Otherwise, the process that is executing the kernel control path is added to the semaphore list and blocked.
[2] 1.6.5.3
Linux offers two kinds of semaphores:
Kernel semaphores, which are used by kernel control paths
System V IPC semaphores, which are used by User Mode processes [2] 5.2.8
The semaphore value is positive if the protected resource is available, and 0 if the protected resource is currently not available. A process that wants to access the resource tries to decrease the semaphore value; the kernel, however, blocks the process until the operation on the semaphore yields a positive value. When a process relinquishes a protected resource, it increases its semaphore value; in doing so, any other process waiting for the semaphore is woken up. [2] 19.3.3
int semget(key_t key, int nsems, int semflg);
int semop(int semid, struct sembuf *sops, unsigned nsops);
int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
struct timespec *timeout);
type struct sembuf containing the following members:
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
sem_flg are IPC_NOWAIT and SEM_UNDO
SAMPLES [3]
/* Oprations on semaphore. */
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
[2] Understanding the Linux Kernel, 3rd Edition By Daniel P. Bovet, Marco Cesati Publisher: O'Reilly Pub Date: November 2005 ISBN: 0-596-00565-2 Pages: 942
[3] http://publib.boulder.ibm.com/infocenter/iseries/v5r3/index.jsp?topic=/apis/apiexusmem.htm
KERNEL THREAD
--------------------
The only difference between a kernel thread and a user thread is the fact that the kernel thread has no user task memory mapping. Like other user processes it shares the kernel address space but the thread operates only in kernel space with kernel privilages.
A thread is normally designed as a continous loop that calls some wait or scheduling function to stop it consuming 100% of the CPU.
Process creat thread
SPIN LOCK
----------------------------
As a general rule, kernel preemption is disabled in every critical region protected by spin locks. In the case of a uniprocessor system, the locks themselves are useless, and the spin lock primitives just disable or enable the kernel preemption. Please notice that kernel preemption is still enabled during the busy wait phase, thus a process waiting for a spin lock to be released could be replaced by a higher priority process. [2] 5.2.4
SEMAPHORES
-------------------------
Why need semaphore?
In general, safe access to a global variable is ensured by using atomic operations . In the previous example, data corruption is not possible if the two control paths read and decrease V with a single, noninterruptible operation. However, kernels contain many data structures that cannot be accessed with a single operation.
The down( ) method decreases the value of the semaphore. If the new value is less than 0, the method adds the running process to the semaphore list and then blocks (i.e., invokes the scheduler). The up( ) method increases the value of the semaphore and, if its new value is greater than or equal to 0, reactivates one or more processes in the semaphore list. [2] 1.6.5
Each data structure to be protected has its own semaphore, which is initialized to 1. When a kernel control path wishes to access the data structure, it executes the down( ) method on the proper semaphore. If the value of the new semaphore isn't negative, access to the data structure is granted. Otherwise, the process that is executing the kernel control path is added to the semaphore list and blocked.
[2] 1.6.5.3
Linux offers two kinds of semaphores:
Kernel semaphores, which are used by kernel control paths
System V IPC semaphores, which are used by User Mode processes [2] 5.2.8
The semaphore value is positive if the protected resource is available, and 0 if the protected resource is currently not available. A process that wants to access the resource tries to decrease the semaphore value; the kernel, however, blocks the process until the operation on the semaphore yields a positive value. When a process relinquishes a protected resource, it increases its semaphore value; in doing so, any other process waiting for the semaphore is woken up. [2] 19.3.3
int semget(key_t key, int nsems, int semflg);
int semop(int semid, struct sembuf *sops, unsigned nsops);
int semtimedop(int semid, struct sembuf *sops, unsigned nsops,
struct timespec *timeout);
type struct sembuf containing the following members:
unsigned short sem_num; /* semaphore number */
short sem_op; /* semaphore operation */
short sem_flg; /* operation flags */
sem_flg are IPC_NOWAIT and SEM_UNDO
SAMPLES [3]
/* Oprations on semaphore. */
union semun {
int val; /* Value for SETVAL */
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */
unsigned short *array; /* Array for GETALL, SETALL */
struct seminfo *__buf; /* Buffer for IPC_INFO
(Linux-specific) */
};
Subscribe to:
Posts (Atom)