thắc mắc Tại sao chương trình không báo lỗi khi khai báo trùng tên biến vậy các cậu?

Riêng C/C++ ông nào bảo "do syntax của ngôn ngữ", "ngôn ngữ nó cho như thế". Thực tế là nói càng. Chính tư tưởng này mà các bố coder chắc chắn sẽ ẩu, cả một project tầm cỡ vài trăm ngàn code mà các bố có tư tưởng "biến trùng tên do ngôn ngữ nó cho phép thế" là up bô cho thằng maintain.

Để tránh tư tưởng nhầm lẫn tai hại này mà C++ nó phải đặt hẳn ra một rule mang tên: One Definition Rule https://en.wikipedia.org/wiki/One_Definition_Rule .Đại ý của luật này là một identifier (định danh) chỉ có duy nhất một definition.

Còn vấn đề trong một chương trình C++ mà 2 biến trùng nhau chương trình vẫn chạy hợp lệ lý do đơn giản: Đây là nguyên tắc scopes trong khoa học máy tính nói chung rồi.
Link wiki đàng hoàng: https://en.wikipedia.org/wiki/Scope_(computer_science)#:~:text=In computer programming, the scope,to refer to the entity.

Nghĩa là một thực thể sẽ được binding với một scope. Vì là nguyên tắc chung của ngành khoa học máy tính, nghĩa là nguyên tắc này nó hình thành từ thuở mà người ta còn phải viết các chương trình bằng Assembly. Nguyên lý scope đã được chứng minh như một tiên đề trong ngành lập trình, thế nên các ngôn ngữ được hình thành sau này dựa theo đấy để hình thành nên bộ quy tắc biên/thông dịch.

Không có ngôn ngữ hay syntax nào lại đi "cho phép" trùng tên biến cả. Mà là do cơ chế scope trong ngành khoa học máy tính nó cho phép thế. Và người ta (những cá nhân, tổ chức) tạo ra các ngôn ngữ lập trình như C/C++ chẳng hạn họ còn phải tạo ra cơ chế Forward Declaration, Namespace, resolution operator... để lập trình viên quản lý các trình tự, phạm vi của các biến, hàm, class.. etc. Để ngăn chặn tư tưởng sử dụng nguyên tắc scope của các lập trình viên một cách ẩu thả bừa bãi.

Ví dụ luôn: Như này là một bug chết người này

C++:
#include<iostream>
using namespace std;
 
// Global x
int x = 0;
 
int main()
{
  // Local x
  int x = 10;
  cout << "Value of global x is " << x; // 10
  cout<< "\nValue of local x is " << x; // 10
  return 0;
}

Còn thế này thì chuẩn cơm mẹ nấu. À mà cũng k nên lạm dụng vì khi viết cỡ 1000-2000 dòng code, tầm vài chục biến trùng tên. Tôi là tôi thề thế éo nào cũng có lúc quên mẹ nó đánh "::" một vài biến. Khác éo gì làm văn viết 2 trang giấy cũng có vài đoạn quên mẹ nó éo chấm câu đâu. :beat_brick:

C++:
#include<iostream>
using namespace std;
 
// Global x
int x = 0;
 
int main()
{
  // Local x
  int x = 10;
  cout << "Value of global x is " << ::x; // 0
  cout<< "\nValue of local x is " << x; // 10
  return 0;
}

Mà tôi đi làm gặp không ít bug của mấy thằng "ngôn ngữ nó cho phép thế" đặt tên biến trùng tên nhưng đếch hiểu bản chất để mà làm cho chuẩn. Chỉnh chúng nó thì gân cổ lên "Ơ em vẫn làm thế mà, syntax nó có sai đâu nhỉ...vẫn compile ổn". Rất là mệt mỏi, tôi chỉ cố làm vài năm nữa là nghỉ dev thôi chứ tôi sợ ngành này lắm rồi.
 
Last edited:
Riêng C/C++ ông nào bảo "do syntax của ngôn ngữ", "ngôn ngữ nó cho như thế". Thực tế là nói càng. Chính tư tưởng này mà các bố coder chắc chắn sẽ ẩu, cả một project tầm cỡ vài trăm ngàn code mà các bố có tư tưởng "biến trùng tên do ngôn ngữ nó cho phép thế" là up bô cho thằng maintain.

Để tránh tư tưởng nhầm lẫn tai hại này mà C++ nó phải đặt hẳn ra một rule mang tên: One Definition Rule https://en.wikipedia.org/wiki/One_Definition_Rule .Đại ý của luật này là một identifier (định danh) chỉ có duy nhất một definition.

Còn vấn đề trong một chương trình C++ mà 2 biến trùng nhau chương trình vẫn chạy hợp lệ lý do đơn giản: Đây là nguyên tắc scopes trong khoa học máy tính nói chung rồi.
Link wiki đàng hoàng: https://en.wikipedia.org/wiki/Scope_(computer_science)#:~:text=In computer programming, the scope,to refer to the entity.

Nghĩa là một thực thể sẽ được binding với một scope. Vì là nguyên tắc chung của ngành khoa học máy tính, nghĩa là nguyên tắc này nó hình thành từ thuở mà người ta còn phải viết các chương trình bằng Assembly. Nguyên lý scope đã được chứng minh như một tiên đề trong ngành lập trình, thế nên các ngôn ngữ được hình thành sau này dựa theo đấy để hình thành nên bộ quy tắc biên/thông dịch.

Không có ngôn ngữ hay syntax nào lại đi "cho phép" trùng tên biến cả. Mà là do cơ chế scope trong ngành khoa học máy tính nó cho phép thế. Và người ta (những cá nhân, tổ chức) tạo ra các ngôn ngữ lập trình như C/C++ chẳng hạn họ còn phải tạo ra cơ chế Forward Declaration, Namespace, resolution operator... để lập trình viên quản lý các trình tự, phạm vi của các biến, hàm, class.. etc. Để ngăn chặn tư tưởng sử dụng nguyên tắc scope của các lập trình viên một cách ẩu thả bừa bãi.

Ví dụ luôn: Như này là một bug chết người này

C++:
#include<iostream>
using namespace std;
 
// Global x
int x = 0;
 
int main()
{
  // Local x
  int x = 10;
  cout << "Value of global x is " << x; // 10
  cout<< "\nValue of local x is " << x; // 10
  return 0;
}

Còn thế này thì chuẩn cơm mẹ nấu. À mà cũng k nên lạm dụng vì khi viết cỡ 1000-2000 dòng code, tầm vài chục biến trùng tên. Tôi là tôi thề thế éo nào cũng có lúc quên mẹ nó đánh "::" một vài biến. Khác éo gì làm văn viết 2 trang giấy cũng có vài đoạn quên mẹ nó éo chấm câu đâu. :beat_brick:

C++:
#include<iostream>
using namespace std;
 
// Global x
int x = 0;
 
int main()
{
  // Local x
  int x = 10;
  cout << "Value of global x is " << ::x; // 0
  cout<< "\nValue of local x is " << x; // 10
  return 0;
}

Mà tôi đi làm gặp không ít bug của mấy thằng "ngôn ngữ nó cho phép thế" đặt tên biến trùng tên nhưng đếch hiểu bản chất để mà làm cho chuẩn. Chỉnh chúng nó thì gân cổ lên "Ơ em vẫn làm thế mà, syntax nó có sai đâu nhỉ...vẫn compile ổn". Rất là mệt mỏi, tôi chỉ cố làm vài năm nữa là nghỉ dev thôi chứ tôi sợ ngành này lắm rồi.
Ngôn ngữ nào cho gọi biến Golbal bằng ::x vậy cậu. Giờ mới biết là có cách gọi biến toàn cầu nếu trường hợp trùng tên.

Cậu là HUST hay UET vậy, thấy nhìn nhận vấn đề rất logic có có tính phản biện.
 
Ngôn ngữ nào cho gọi biến Golbal bằng ::x vậy cậu. Giờ mới biết là có cách gọi biến toàn cầu nếu trường hợp trùng tên.

Cậu là HUST hay UET vậy, thấy nhìn nhận vấn đề rất logic có có tính phản biện.
Tôi đi làm 7 năm nay sắp nghỉ nghề dev rồi. HUS hít HN
 
thì bật flag -Wshadow hay /W4 gì lên là xong hết. Còn ghét nữa thì thêm -Werror hay /WX vào là thành lỗi, thằng nào shadow được nữa
JiZo9zf.png


Mà ODR đâu có liên quan tới đặt tên này đem vào làm gì, giống như ví dụ đem cái DRY vào để bàn đừng đặt tên trùng, chả liên quan.
Thứ nhất tôi nói a hay. Trong 1 dự án đến giai đoạn release build, một module sẽ viết bởi nhiều người. Project lại nhiều module hợp lại. Ai cho anh cắm flag theo ý a trong makefile? Còn a viết dự án cá nhân của a, a cắm flag thế nào tùy anh thì a muốn cắm bao nhiêu file, cắm thế nào tùy a. Đi làm thì không có trò đấy đâu. Đến việc đặt tên biến còn có luật riêng của team nữa, rồi còn đặt theo luật riêng của cty, cty rồi lại đặt theo luật của khách hàng. Việc đặt tên biến khá là nghiêm ngặt ấy vậy mà vẫn có mấy anh phó mặc cho việc cắm cờ chờ trình biên dịch nó warn cho. Vấn đề nó lại nằm ở việc đến đoạn release build người ta đi cắm flag cho anh chắc. Khi release xong xuôi, ngon nghẻ nhưng bug to đùng như phía trên tôi ví dụ thì bọn maintain nó vái lạy, chửi rủa các anh luôn.

Thứ 2 ODR là rule trong C++, ai bảo anh nó không liên qua đến việc đặt tên biến. Anh đang bị nằm mơ giữa việc lập trình và đặt tên nick yahoo chat à? Việc a đặt tên biến trong C++ đồng nghĩa a đang declaration hoặc definition biến ấy thì ODR nó chẳng dí thẳng vào ấy mà bảo không liên quan.
 
Thứ nhất tôi nói a hay. Trong 1 dự án đến giai đoạn release build, một module sẽ viết bởi nhiều người. Project lại nhiều module hợp lại. Ai cho anh cắm flag theo ý a trong makefile? Còn a viết dự án cá nhân của a, a cắm flag thế nào tùy anh thì a muốn cắm bao nhiêu file, cắm thế nào tùy a. Đi làm thì không có trò đấy đâu. Đến việc đặt tên biến còn có luật riêng của team nữa, rồi còn đặt theo luật riêng của cty, cty rồi lại đặt theo luật của khách hàng. Việc đặt tên biến khá là nghiêm ngặt ấy vậy mà vẫn có mấy anh phó mặc cho việc cắm cờ chờ trình biên dịch nó warn cho. Vấn đề nó lại nằm ở việc đến đoạn release build người ta đi cắm flag cho anh chắc. Khi release xong xuôi, ngon nghẻ nhưng bug to đùng như phía trên tôi ví dụ thì bọn maintain nó vái lạy, chửi rủa các anh luôn.

Thứ 2 ODR là rule trong C++, ai bảo anh nó không liên qua đến việc đặt tên biến. Anh đang bị nằm mơ giữa việc lập trình và đặt tên nick yahoo chat à? Việc a đặt tên biến trong C++ đồng nghĩa a đang declaration hoặc definition biến ấy thì ODR nó chẳng dí thẳng vào ấy mà bảo không liên quan.
Lạc đề rồi thím :D
Chỉ nói là compiler có báo lỗi/cảnh báo không chứ đâu có nói gì đến “nên” đặt hay không.
 
tôi thì thấy cái ODR chả liên quan tới cái shadow này. ODR là cấm x::y định nghĩa 2 lần chứ đâu có cấm đặt tên ::y, x::y, z::y, hay y giống tên nhau. Trùng tên thì phải khác họ chứ có phải ODR là để tránh "tư tưởng" này đâu. Nói ODR là muốn tránh trùng tên thì khác gì nói nguyên tắc DRY là muốn tránh lập lại cái tên
Xv0BtTR.png


còn đặt tên mà theo luật của cty thì cty có luật khắt khe rồi sao lại để mấy thằng nào nó shadow tên này tên nọ
Xv0BtTR.png
code vi phạm ODR đây tôi ví dụ 1 case cho a dễ hình dung. Nó còn inline func trong namespace, trong class...struct chưa là gì đâu:
C++:
/* a.cpp */
struct Rect
{
    int x,y,w,h;
    Rect(): x(0),y(0),w(0),h(0)
};
/* b.cpp */
struct Rect
{
    double x,y,w,h;
    Rect(): x(0),y(0),w(0),h(0)
};

ODR là luật k chỉ là quản việc doublue resolution operator như a nghĩ đâu.

Còn việc dev cứng đầu phó mặc cho việc cắm flag warn lỗi thì đấy là do thói quen làm ẩu của họ. Chứ rule cty không thể quản hết được. Nhiều a đi làm còn thể hiện lắm chứ k đùa được, cắm flag optimizing compiler loạn hết lên, compile chạy lược bớt logic bug loạn lên còn chưa biết bug ở đâu nó nhảy ra kìa.
 
Lạc đề rồi thím :D
Chỉ nói là compiler có báo lỗi/cảnh báo không chứ đâu có nói gì đến “nên” đặt hay không.
Tôi dạo này lên voz đọc cmt hình như tôi cũng như trên mây. Cái nghề dev này dễ rơi vào trạng thái phê cần. Chắc phải nghỉ một thời gian.
 
Thấy nhiều thím vào thể hiện ghê quá. T thấy thớt hỏi sao chương trình không báo lỗi khi trùng tên biến mà khác scope thì t nói đó không phải lỗi, compiler nó không báo là đúng rồi. Còn chuyện có nên đặt tên biến trùng như vậy hay không thì lại liên quan đến coding convention rồi, đó là một cây chuyện khác nữa, :beat_brick:
 
Back
Top