[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]] 

Java also uses compiler. So, if we meet with compile error, we need to check compile option.

[Cases]
Error : "Access restriction : the field ..." [in Eclipse]

'Project' -> 'Properties' -> 'Java Compiler' -> 'Errors/Warnings' -> 'Deprecated and restricted API' -> Forbidden reference (access rule) -> change from 'Error' to 'Warning'.
=> We can make compile success. But, please keep it mind... using forbidden reference is not recommended!!

Using external Jar [in Eclipse]

Right click on Project -> Properties -> select 'Java Build Path' -> select 'Libraries' tab -> select 'Add External JARs' button...

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]
 

In MSVC 2008 Express, following code raises error.

template  class A
{
    int   Func(int (*f)(const T, const T));
}

static int TagF(const Tag* a, const Tag* b){...}

int main()
{
    A a;
    a.Func(TagF); // error : type of 1st parameter is mismatch...bla-bla...
}

Intersetingly, following is well-compiled in MSVC 2008 Express.

// Definition of Class A is same with above.

typedef Tag*  PTag;
static int TagF(const PTag a, const PTag b) {...}

int main()
{
    A a;
    a.Func(TagF);
}

Is it a bug of MSVC? or Do I miss something????

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

In terms of function's return value, I classify three types.

type 1 : Function may fail with quite high possibility. 
return value tells details about success or fail reason.
Ex.)

return_value == 0 : general success.
return_value > 0 : success with additional information [value represents additional information]
return_value < 0 : fails [value represents error code]

int open_service(...) {...}

type 2 : Function may fail with very low possibility.
return value tells the result or "success or fail".
Ex.)

return_value == NULL : fails.
otherwise : return_value is result.

Item* List::next() {...}
FILE* fopen(...) {...}

In this case, we may need additional function like "get_last_error()" - like MSVC's API.

type 3 : Function never fails.
return value is result, 'void' or instance itself to easy-next-use.
Ex.)

int get_id() {...}
void set_color(int color) {...}
Paint* Paint::set_color(int color) {...; return this;}

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]
 

There two type of using 'new' operator.

new Type(param);
new Type[size];

'new' is operator. So, parameter is followed by. Therefore, we should take care of using '()'.
Here is test result on MSVC7.

(*1)

new (Typename(param)); // -- compile error
new (Typename)(param); // -- OK
new (Typename[size]);  // -- OK
new (Typename[size])(); // -- OK
new (Typename)[size];  // -- compile error
new (Typename[size])(param); // -- compile error

Interestingly, 'Type[size]' itself seems to be regarded as type. That is,

int a[10]; // 'sizeof(a)' works

similarly

Type[10]; // 'sizeof(Type[10])' works.

Considering 'Type[size]' as a kind of type may not be true. But, I think it's similar with the case of pointer - pointer is type of not. Only to understand things easily, personally, I will regard it as type.

Let's see (*1) from "C operator"'s point of view - 'new' also a kind of operator.

operator new ( Typename(param) ); //  (*a)
operator new (Typename) (param); // (*b)
operator new (Typename[size]); // (*c)
operator new (Typename[size])(); // (*d)
operator new (Typename)[size]; // (*e)
operator new (Typename[size])(param) // (*f)

(*a) : 'Type(param)' is syntax for create instance. Not type name.
(*b) : '(param)' is parameter of instance created by '(operator new(Typename))'
(*c) : 'Typename[size]' is just a type. So, no problem!
(*d) : same with above. It's like "calling default constructor of newly created instance".
(*e) : This is a form like "instance[size]" - (operator new (Typename))[size]. Array should be declard with type (Not instance).
(*f) : (operator new (Typename[size])) (param). This is like "calling constructor whose parameter is '(param)'". But, ISO C++ forbids initialization in array new.

Hmmm..... Interesting.....

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

Constructor doesn't give return value!.
Yes, we can pass pointer as parameter and get value. But it's not good shape.
So, we shouldn't write code that may prevent class from instanciation in constructor. And, we may need additional interface for initializing that can give return value - like 'int init()'.
[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

Using 'const' wherever possible is very very important. It can help to avoid mistakes and increase readability very much.
Personally, I even regard ability of using 'const' in code, as one of most important evidence to evaluate programmer's quality.

==== const member function ====

class A {
    void funcB(void) const;
    void funcA(int* pa) const;
    int* funcC(void) const;
    int a
}

const member function(henceforth const member) cannot change class member variable. And, const member can call only const member. But, const member can call any C function.
By the way, there is no constraints about parameter in const member. So, following is possible.

Hack 1
  void A::funcB(void) const { funcA(&a); }
  void A::funcA(int* pa) const { *pa = 9; }

Hack 2
  void A::funcB(void) const ( int* p = funcC(); *p = 8; }
  int* A::funcC(void) const {return &a;}

Even if, funcB changes value of member variable, it compiles well. This is one of week points of const member.

==== const & pointer ====

const int* p;   // *1 - (*p) is const
int const *p;   // *2 - (*p) is const
int* const p;   // *3 - (p) is const

case *1, *2;

"*p = 4" is error, but, "p = &b" is OK.
So, we can hack this like "*((int*)p) = 9;".

case *3

contrary to upper case. So, we should initialize pointer before using it.

==== const & multiple pointer ====

const int** p;   // *1
int const **p;   // *2
int* const *p;   // *3
int** const p:   // *4

int*       pb;
const int* cpb
int b;

case *1, *2.

// p = &pb; // error - "cannot convert from 'int **' to 'const int **"
p = &cpb; // OK.
*p = &b;
// **p = 8; // error - "you cannot assign to a variable that is const"
*((int*)*p) = 8 // OK. Hack!

case *3

p = &pb; // OK
*p = &b; // error - "you cannot assign to a variable that is const"

case *4

p = &pb; // error - "you cannot assign to a variable that is const". p should be initialized before used.

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

What is variable in C? Let's think about this deeply.

The variable consists of type and name.
Then, what is 'type'? and what is name?
'type' is "What the memory value means"; Way of interpreting memory.
'name' is alias of memory address.

Can you understand?
We can know that 4-byte-memory-value from address '&a' represents 'signed integer value' from C code "int a;".

Following example(ARM assembly and C codes) shows this explicitly.

// asm.s
EXPORT my_symbol
CODE32
my_symbol
DCD 0x73d71034

------------

// symbol.c
extern char* my_symbol;
int data = (int)my_symbol;
[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

Nothing to say in detail about this. "Complex dependency between selective-compile-switches" means "despair, hopelessness, nightmare..."

'Language > C&C++' 카테고리의 다른 글

[C/C++] 'const' keyword.  (0) 2009.03.11
[C/C++] What is 'variable'??  (0) 2009.01.24
[C/C++] Using static variable in large-size-file.  (0) 2008.09.09
[C/C++] Indirect branch...  (0) 2008.07.26
[C/C++] Take care of using shallow copy!  (0) 2008.06.04
[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

There is several important reason trying to avoid using global variable. One of them is "Tracking usage is very difficult.". It is extremely difficult for developer to know enough when this variable is used and changed.
It is also true for static variable in C and member variable in C++, JAVA and so on. Let's focus on the case of static variable in C (the case of member variable is also same.).
In simple and short file (ex. less than 500 lines), it's not matter. But, static variable in large-size-file is also difficult to track. Yes, we should keep file small. But in practice, this case is not rare. Whenever we use static variable in large-size-file, we should take care of it. Especially, using flag and state is top of that. In many cases, flag and state are used to branch. So, tracking these values are very important. Let's see following example.

static int _b_ui_mode = FALSE;
static int _operational_mode = IDLE;
funcA ()
{
  ...
  _b_ui_mode = TRUE;
  _operational_mode = USER_INPUT;
}
...
funcP()
{
  if(_operational_mode == IDLE){
    ...
  }
}
...

This is bad example. Assigning value to the static variable directly - especially to the flag and state variable - is the main reason to make tracking software difficlut. At least we should use get()/set() function.; Even in worst case, this makes logging easy. This is minimal requirement to use static variable in large-size-file.

[[ blog 이사 과정에서 정확한 posting날짜가 분실됨. 년도와 분기 정도는 맞지 않을까? ]]

"indirect branch" means "branching into value of register". Usual branching jumps to the address computed from argument value and PC - PC relative address. So, there is offset limitation. But, 'indirect jump' can go to anywhere within supported address - usually, register size == instruction domain size == supporting memory size.

Here ARM example.

BX LR,
LDR PC, XX,
ADD PC, XX, XX

Then, which case can be interpreted to 'indirect branch' in C/C++ - Yes, it's totally dependent on compiler. We just assume general case?

* Return from function call. (BX LR)
* Function call by "function pointer" (LDR PC, XX)
    - using function pointer explicitly.
    - using virtual function pointer table of class.
... anything else???

+ Recent posts