This page is READ-ONLY. It is generated from the old site.
All timestamps are relative to 2013 (when this page is generated).
If you are looking for TeX support, please go to VietTUG.org

const isn't constant

constant vẫn bị thay đổi giá trị như thường
Added by bronzeboyvn almost 3 years ago  »  Votes: 1/1

Constant mà không phải là constant.

 1 #include <stdio.h>
 2 
 3 int main()
 4 {
 5     const int nights = 1001;
 6     const int *cpointer = &nights;
 7     int *pointer;
 8 
 9     pointer = (int *)cpointer;
10     *pointer = 9;
11     printf("nights = %d\n", nights);
12 
13     return 0;
14 }

Cho biên dịch bằng compiler gcc với tham số -Wall, không có warning nào.
Chạy chương trình, output sẽ là nights = 9. Ngôn ngữ không có lỗi, compiler không có lỗi. C là ngôn ngữ vạn năng. Lỗi là do ta không biết mình đang làm gì.


Comments

Added by almost 3 years ago

Compiler mà không báo lỗi này thì thật kỳ lạ :(

Added by hoangtran almost 3 years ago

Tiec la -Wall khong turn on cai -Wcast-qual len. Thu cai -Wcast-qual se thay warning ngay.

Trang manual cua gcc co:

-Wall turns on the following warning flags:

-Waddress -Warray-bounds (only with -O2) -Wc++0x-compat -Wchar-subscripts -Wimplicit-int -Wimplicit-function-declaration -Wcomment -Wformat
-Wmain (only for C/ObjC and unless -ffreestanding) -Wmissing-braces -Wnonnull -Wparentheses -Wpointer-sign -Wreorder -Wreturn-type
-Wsequence-point -Wsign-compare (only in C++) -Wstrict-aliasing -Wstrict-overflow=1 -Wswitch -Wtrigraphs -Wuninitialized -Wunknown-pragmas
-Wunused-function -Wunused-label -Wunused-value -Wunused-variable -Wvolatile-register-var

Added by almost 3 years ago

CT gặp cao thủ rồi :)

Added by almost 3 years ago

Sợ anh Hoàng thật :D

Added by phucluoi almost 3 years ago

Ho ho, cai nay dan hoc C phai biet chu nhi, it nhat la hoc C voi linux. Ben C++ con co chieu nua hay lam co: goi call by ref:

class Y{
   ....
};
class X{
    void foo(const Y &y)
    {
         // o day van co the thay doi gia tri cua
         // bien y, mac du la const, va call by ref
         // bang pointer :
         Y* evilPointer = &y;
         // make something here with evilPointer :D
         return void;
    }

};

Added by almost 3 years ago

Mình học C trong ... DOS :D

Ý của phucluoi là ta có thể thay đổi giá trị của const một cách hợp lệ?

Added by phucluoi almost 3 years ago

Khong phai the, dai khai y em la, muc dich khai bao argument const Y &y la de cho "an toan", nghia la methode foo khong co thay doi bat ki gia tri cua cac atribute cua y.
Neu methode foo ma "tay may" cac atribute cua y (chang han goi cac setXXX methodes cua y) thi compiler se bao loi. Nhung ma neu bac khong "tay may" truc tiep ma thong qua mot pointer thi compiler khong bao gi het neu xai -Wall, co nhung cai khac em khong biet.

Cach khai bao const duoc ap dung chang han trong truong hop Y la mot single ton (cha biet tieng Viet la gi) va luu cac cau hinh, cac object khac nhau trong 1 chuong trinh cung doc cac cau hinh cua "y".

Neu em nho khong lam thi Window$ khong co san bat ki mot compiler nao het, tu C cho toi C++, Pascal. Muon hoc mot ngon ngu lap trinh nao trong moi truong Window$ thi dieu truoc tien la phai kiem trinh dich. Ngon ngu duy nhat ma Window$ ho tro nativ la batch. :D

Noi chung Window$ la ... ke thu cua lap trinh vien. Chi noi may cai vu click click de cau hinh cho no la thay ngan ngam roi.

Added by almost 3 years ago

Cảm ơn phucluoi đã giải thích :)

Vụ Windows thì đúng rồi. Nhưng hồi xưa chưa biết Linux, bắt đầu học lập trình C, C++ với DOS, Windows, dù sao cũng phải.. mang ơn nó :D

TB: Dạo này bài viết không dấu nhiều quá :D, cài thêm bộ gõ vô thì đúng là oải đây :D

Added by bronzeboyvn almost 3 years ago

Thay đổi const là hợp lệ. Nếu lỗi thì đã bị error khi compile, chứ không phải là warning.
const int nights nghĩa là nights chứa ở nơi read-only. Nhưng một khi đã nắm được địa chỉ mà nó trỏ vào, thì làm gì cũng được.
Có những trường hợp ta cần "ngược ngạo" như vậy. Thằng client nắm nights, nó chỉ đọc dữ liệu về. Thằng server lại thay đổi giá trị của nó thường xuyên. Khai báo kiểu như const volatile unsigned int abc;, tụi làm real-time system nó làm như cơm bữa.

Added by bronzeboyvn almost 3 years ago

Cú này anh Hoàng vô cứu em!

 1 #include <iostream>
 2 using namespace std;
 3 
 4 int main()
 5 {
 6     const int nights = 1001;
 7     const int *cpointer = &nights;
 8     int *pointer;
 9 
10     pointer = (int *)cpointer;
11     *pointer = 9;
12     cout << "*pointer = " << *pointer << "\t address: " << pointer << endl;
13     cout << "nights = " << nights << "\t address: " << (&nights) << endl;
14 
15     return 0;
16 }

Compile bằng g++: pointer trỏ vào nights, sao *pointer = 9 còn nights = 1001 ?
Có thể compiler g++ mặc định rằng

pointer = (int *)cpointer;

tương đương với
pointer = const_cast <int*> (cpointer);

???

Added by hoangtran almost 3 years ago

Trời ơi, post vào đây thì anh sao biết được. Hiện tại chỉ khỉ có bài mới thì anh mới nhận qua google reader thôi. Chứ comment mới thí bó tay :-D Chịu khó bắn một phát vào facebook nhá :-D

Thực ra ở cái ví dụ của chú thì vấn đề không phải C hay C++ mà là ở trình biên dịch. Anh tin là đưa sang C thì kết quả cũng thế thôi. Bản chất là ở quá trình optimize của trình biên dịch. Tất cả các trình biên dịch hiện đại bây giờ đều rất thông minh. Từ đoạn mã trên, nó nhìn thấy nights là một biến const nên hiểu là trong hàm main nó không thay đổi gì, nên khi gọi cout

Added by hoangtran almost 3 years ago

Để ra kết quả như ý nghĩ của chú thì có thêm volatile (mục đích là báo cho trình biên dịch là mày làm ơn đừng optimize tao mà cứ dịch theo cách tao phải là :-D ) vào là ngon ơ

 1 $ cat testconst.cpp 
 2 #include <iostream>
 3 using namespace std;
 4 
 5 int main()
 6 {
 7     volatile const int nights = 1001;
 8     volatile const int *cpointer = &nights;
 9     volatile int *pointer;
10     pointer = (volatile int *)cpointer;
11     *pointer = 9;
12     cout << "*pointer = " << *pointer << "\t address: " << pointer << endl;
13     cout << "nights = " << nights << "\t address: " << (&nights) << endl;
14     return 0;
15 }
16 
17 $ g++  -o testconst testconst.cpp
18 
19 $ ./testconst 
20 *pointer = 9     address: 1
21 nights = 9     address: 1

Chả hiểu sao address là 1 nữa haha

Added by almost 3 years ago

Trời ơi, post vào đây thì anh sao biết được. Hiện tại chỉ khỉ có bài mới thì anh mới nhận qua google reader thôi. Chứ comment mới thí bó tay :-D Chịu khó bắn một phát vào facebook nhá :-D

hoangtran: bác vào trang hoạt động rồi ỏ phần navigation chọn vào bình luận blog / tin tức, chọn Áp dụng rồi sau đó chọn Atom link. Hoặc là bác điều chỉnh feed bằng cách mở cài đặt của google reader vào thêm show_ping_news=1 vào liên kết đã có. Dưới đây là một ví dụ

http://freebox.vn/projects/bronzeboyvn/activity.atom?show_news=1&show_files=1&show_ping_news=1&show_blogs=1

Added by bronzeboyvn almost 3 years ago

Cám ơn anh Hoàng nhiều nha!
Cuối tuần cafe đi anh KA. Kiếm quán nào ở vị trí trọng tâm của 3 người đi cho gần gần :)

Added by anhhk almost 3 years ago

Ok, để anh liên lạc lại qua điện thoại.