Definición de la función no se encuentra para una función declarada en el interior de espacio de nombres sin nombre – de cómo resolver? (Visual Studio 2015)

He instalado Visual Studio 2015 y encontró que algunos de mi código (que no había ningún problema en que VS 2013) ahora tiene algunos errores indicado por el verde de los garabatos (que se supone que son una nuevas características de productividad). Sin embargo, el código se compila correctamente.

Aquí está un ejemplo rápido:

namespace
{
    void test1(); //what once was OK in VS 2013,
    void test2(); //is now marked with squiggles in VS 2015
}

namespace named
{
    void test3(); //OK, no problem
}

void        test1() { /*...*/ }
void      ::test2() { /*...*/ }
void named::test3() { /*...*/ }

int main() { /*...*/ }

Estos son los garabatos en cuestión

Definición de la función no se encuentra para una función declarada en el interior de espacio de nombres sin nombre - de cómo resolver? (Visual Studio 2015)

Moviendo el ratón sobre ellos me dice que

Definición de la función para ‘test1’ no se encuentra

Definición de la función para ‘prueba2’ no se encuentra


De alguna manera resulta que sólo las funciones declaradas en el interior de espacio de nombres sin nombre desencadenar la garabatos.

¿Cómo se supone que ser resueltos?

  • Por favor, código postal, en lugar de la imagen del código.
  • Cada vez que una imagen de código se registra un gatito muere. Por favor, por favor, no hagas eso.
  • Usted probablemente tendrá que definir las funciones dentro de un espacio de nombres así, supongo? O si el código se compila como es, simplemente lo ignoran y achacarlo a la aún más Intellisense rareza.
  • He oído que no hay gatitos mueren si una imagen es reemplazada con un código en menos de 12 horas… ‘-.-‘
  • ¿Qué sucede si usted pone las definiciones de función en el espacio de nombres anónimos, no sólo de las declaraciones? No puedo pensar en una buena razón para tener las declaraciones fuera del espacio de nombres. A mí me parece que usted es la repetición innecesaria de sí mismo (violando SECO) tener tanto la declaración y definición.
  • Tenga en cuenta que esto también puede suceder si IntelliSense es incapaz de analizar la definición de la función debido a la macros o (en mi caso) IntelliSense-errores al utilizar uniforme sintaxis de inicialización de punteros

InformationsquelleAutor sunny moon | 2015-08-09

2 Kommentare

  1. 3

    El verde de los garabatos no te dicen que hay un error, ellos te dicen que hay una oportunidad para que las nuevas herramientas de refactorización para hacer algo. (Rojo garabatos indicar un error.) En este caso, se está informando a usted que no hay ninguna definición que coincide con la declaración de test2, por lo que el IDE se ofrece para generar una.

    Esto sucede para señalar un error que siempre estuvo allí, en el código, a pesar de Visual Studio puede estar comportándose de un disconforme manera.

    Entonces, ¿qué pasa? El problema es que las declaraciones en el espacio de nombres sin nombre no declarar las mismas funciones que posteriormente se definen en el espacio de nombres global. Las herramientas de refactorización reconocer esto y ofrecer a generar una definición de las funciones declaradas.

    Sin embargo, la cosa todavía se compila, debido a que el compilador de Microsoft aceptar dos estrictamente ilegal piezas de código. En primer lugar, utilizando el prefijo de espacio de nombres en la primera declaración de una función no está permitido. El código en main entonces, presumiblemente, las llamadas a las funciones. Como Alex M mostró en su respuesta, GCC no voy a aceptar esto, ya que la llamada es ambiguo. El compilador de Microsoft parece aceptarlo, ya sea el tratamiento de la definición como una definición que coincide con la declaración en el espacio de nombres sin nombre (recuerde, las herramientas del IDE, IntelliSense y el refractario, utiliza el más compatible con EDG front-end, no el analizador de la real compilador utiliza, lo que significa que el refractario puede decir que la declaración no tiene definición, mientras que el compilador trata de la definición como la coincidencia de la declaración), o simplemente prefieren la versión global a los nombres de espacios de versión.

    Es fácil distinguir los dos casos, por el camino. Reorganizar el código para que main viene antes de las definiciones de función. Esto va a resolver la ambigüedad en el GCC, porque sólo los nombres de espacios de función se declara (y no definido, por lo que debe obtener un error del vinculador). También llevará a un enlazador de error en el compilador de Microsoft, si prefiere la versión global, pero todavía se compila si se trata de la declaración y la definición como la coincidencia.

    La solución a todo esto es muy sencillo: cuando la definición de las funciones declaradas en el espacio de nombres sin nombre, acaba de abrir el espacio de nombres en lugar de tratar de definir las funciones en el exterior.

  2. 2

    Esto compila bien, con la luz de la bombilla que usted ha mencionado:

    namespace
    {
        void func();
    }
    
    void ::func() //Will not compile if 'void func()'
    {}
    
    int main()
    {
        func();
    }

    Pero IntelliSense también salidas (en ambos casos):

    Error (active) more than one instance of overloaded function "func"
    matches the argument list: 
    
    function "func()"
    function "<unnamed>::func()"

    Es esto realmente lo que quieres hacer? Como n4527 en § 7.3.1.1 estados:

    Un sin nombre-espacio de nombres-definición se comporta como si fuese reemplazado por

    inline(opt) namespace unique { /* empty body */ } 
    using namespace unique; 
    namespace unique { namespace-body }

    en línea donde aparece el si y sólo si aparece en la
    sin nombre-espacio de nombres-definición y todas las apariciones de único en una unidad de traducción son reemplazados por el mismo identificador, y este
    identificador difiere de todos los otros identificadores en la unidad de traducción.

    Que deja en claro por qué hay ambigüedades pasando. Basta con definir sus métodos de dentro de su espacio de nombres sin nombre, como que son diferentes de cualquier otra cosa fuera de él.

    Para el registro, GCC 5.2.0 y clang 3.6.0 que no está de acuerdo para compilar el código que MSVC compilado.

    • Por cierto, en el último ejemplo func definición debe incluir el prefijo UniqueNameInTU:: así. using namespace sólo permitiría a los ejecutar sin el prefijo después se define.
    • No estoy seguro de que debe como prefijo. Estás diciendo que debería de ser, pero de acuerdo a qué?
    • Si la definición no es el prefijo, el verde de los garabatos bajo func declaración todavía están allí, aunque se compila. Que es lo que quiero decir.
    • Usted no puede prefijo, ya que su espacio de nombres sin nombre. Era sólo un ejemplo de lo que sucede durante el proceso de compilación, en el fondo. Echa un borrador de la norma en 7.3.1.1 Unnamed namespaces (yo usé n4527) si usted necesita ayuda adicional en la comprensión de lo que significaba. Básicamente, estoy tratando de decirte que los garabatos son su razón de ser allí, y Microsoft el compilador que se está portando mal.
    • Gracias por tu paciencia, Alex. Su analogía con using namespace es claro para mí ahora. Aún así, traté de compilar mi ejemplo con gcc 4.9.3 y no de compilación debido a :: en frente de test2 definición en la línea 13 – no debido a la función no está definida fuera de espacio de nombres sin nombre.
    • En realidad, volver a leer lo que he dicho aquí muchas veces como sea necesario, creo que he explicado lo suficiente. Por lo que vale con 5.2.0 coliru.stacked-crooked.com/a/523e213da0546aa0

Kommentieren Sie den Artikel

Bitte geben Sie Ihren Kommentar ein!
Bitte geben Sie hier Ihren Namen ein

Pruebas en línea