代码之家  ›  专栏  ›  技术社区  ›  dimba

gcc-Wshadow太严格了?

  •  16
  • dimba  · 技术社区  · 16 年前

    class A
    {
      public:
        int len();
        void setLen(int len) { len_ = len; } // warning at this line
      private:
        int len_;
    };
    

    main.cpp:4: warning: declaration of `len' shadows a member of `this'
    

    函数len和整数len的类型不同。为什么要发出警告?

    更新

    然而,这面旗帜并不实用。例如,常用的setter/getter成语:

    class A {
       void prop(int prop);  // setter
       int prop() const;     // getter
    
       int prop;
    };
    

    如果有一个警告标志在这种情况下不会发出警告,但在“int a”隐藏“int a”的情况下会发出警告,那就更好了。

    我不介意怎么称呼它,更实用,更有趣,或者

    那么,有吗 其他 gcc的警告标志做什么我描述?

    link text . 我并不孤单:) 不那么严格的检查可能会有用得多。

    5 回复  |  直到 7 年前
        1
  •  24
  •   Joseph Quinsey Taseen    12 年前

    这似乎在新版本的GCC上得到了解决。

    From version 4.8 changelog :

    The option -Wshadow no longer warns if a declaration shadows a function declaration,
    unless the former declares a function or pointer to function, because this is a common
    and valid case in real-world code.
    

    https://lkml.org/lkml/2006/11/28/253

    不幸的是,我目前工作的嵌入式系统的最新编译器仍然基于GCC4.6。

        2
  •  16
  •   James McNellis    16 年前

    参数与成员函数具有不同的类型这一事实并不影响该参数隐藏成员函数这一事实。

        3
  •  10
  •   AnT stands with Russia    16 年前

    我不明白你为什么只坚持一些特定类型的阴影。阴影就是阴影,它的危险是相同的,即使类型不同,即使一个变量阴影一个函数,就像你的例子一样。隐藏的危险在于代码可能会做一些不同于其作者希望它做的事情。

    struct L { 
      void operator ()(); 
    };
    
    struct A {
      void len();
    
      A(L len) {
        len();
        // Intended to call the member function. Instead got a call to the functor
      }
    };
    

    我认为这是非常明显的,因为代码的阴影可能会做一些作者不打算做的事情。

        4
  •  7
  •   Stack Overflow is garbage    16 年前

    它完全按照盒子上写的做。它警告你不要跟踪。

    内部 setLen 函数的作用域中有两个共享同一名称的符号。 len 是函数参数的名称,也是函数的名称。

    一个 阴影 另一个的名称,所以在编写代码时 ,你可能得不到你想要的结果。因为你让编译器警告你符号 阴影 对彼此来说,这就是它警告你的。

        5
  •  4
  •   Daniel E.    6 年前

    GCC >= 7 -Wshadow 对程序员的心智有不同的影响。从GCC 9.1.0手册页:

    • -Wshadow=global

    • -Wshadow=local

    当局部变量与另一个局部变量或参数有阴影时发出警告。此警告由-Wshadow=global启用。

    • -Wshadow=compatible-local

    当一个局部变量与另一个局部变量或参数的类型兼容时发出警告。在C++中,类型兼容性在这里意味着阴影变量的类型可以转换为阴影变量的类型。创建此标志(除了 -Wshadow=本地 )基于这样一种想法,即当一个局部变量隐藏另一个不兼容类型的变量时,很可能是故意的,而不是错误或打字错误,如以下示例所示:

                   for (SomeIterator i = SomeObj.begin(); i != SomeObj.end(); ++i)
                   {
                     for (int i = 0; i < N; ++i)
                     {
                       ...
                     }
                     ...
                   }
    

    i “在上面的示例中,有不兼容的类型,仅启用 不会发出警告。因为它们的类型是不兼容的,如果程序员不小心使用了其中一个来代替另一个,类型检查将捕获该类型并发出错误或警告。因此,在这种情况下不发出警告(关于阴影)不会导致未检测到的错误。使用此标志而不是 可能会减少由有意跟踪触发的警告数。

    -Wshadow=本地 .

        6
  •  2
  •   Mehul Mistri    13 年前

    是的,我们可以调整这个警告,以警告只有当阴影可能是危险的。

    int what()常量。。

    但是对于局部变量阴影和上面的函子示例,警告。

    更确切地说,当阴影可能是危险的,当代码编写器的意图可能不清楚时,发出警告。在int参数和成员函数同名的情况下,作者显然不希望在引用该参数时调用该成员。

    我觉得这个阴影警告是一个好主意,非常有用,它只是需要更多的思考,不要警告完全安全和明确的情况。例如,我可以接受需要前缀之类的参数,但我更喜欢简洁明了的名称。

        7
  •  0
  •   fwyzard    6 年前

    问题部分:

    class A {
       void prop(int prop);  // setter
       int prop() const;     // getter
    
       int prop;
    };
    

    这只是一个错误;成员变量和方法不能同时具有相同的名称。

    对于您的示例,提供工作界面的最小更改是:

    class A {
    public:
      void prop(int prop);  // setter
      int prop() const;     // getter
    
    private:
       int prop_;
    };