Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

542
Views
MSVC vs GCC & Clang Bug al usar lambdas

Estaba probando un ejemplo presentado en CppCon que usa lambdas . Y para mi sorpresa, el programa no compila en gcc y clang (en C++ 14 o C++ 17), sino que compila en msvc. Esto se puede verificar aquí .

Como referencia, el código de ejemplo es el siguiente:

 #include <stdio.h> int g = 10; auto kitten = [=]() { return g+1; }; auto cat = [g=g]() { return g+1; }; int main() { g = 20; printf("%d %d\n", kitten(), cat()); }

¿Cuál es el problema aquí (si lo hay) y qué compilador es el correcto?

Tenga en cuenta que el código es un copiado y pegado exacto de su diapositiva de presentación oficial.

over 4 years ago · Santiago Trujillo
2 answers
Answer question

0

Este es un problema con MSVC. clang y g++ son correctos.

De [expr.prim.lambda.capture]/3 (C++17 borrador N4659)

Una expresión lambda cuyo ámbito envolvente más pequeño es un ámbito de bloque (6.3.3) es una expresión lambda local; cualquier otra expresión lambda no tendrá una captura predeterminada o una captura simple en su introductor lambda. El ámbito de alcance de una expresión lambda local es el conjunto de ámbitos envolventes hasta la función envolvente más interna y sus parámetros, inclusive. [ Nota: este ámbito de alcance incluye cualquier expresión lambda intermedia. —nota final]

Dado que = es una capture-default y la lambda no está dentro de un alcance de bloque, el código no es válido.

over 4 years ago · Santiago Trujillo Report

0

¿Cuál es el problema aquí (si lo hay)

Preguntemos qué tienen que decir los compiladores que se niegan a compilar:

 error: non-local lambda expression cannot have a capture-default

Veamos qué dice la norma:

C++14 borrador N4140

Una expresión lambda cuyo ámbito envolvente más pequeño es un ámbito de bloque ([basic.scope.block]) es una expresión lambda local; cualquier otra expresión lambda no tendrá una captura predeterminada o una captura simple en su introductor lambda. El ámbito de alcance de una expresión lambda local es el conjunto de ámbitos envolventes hasta la función envolvente más interna y sus parámetros, inclusive. [ Nota: este ámbito de alcance incluye cualquier expresión lambda intermedia. - nota final]


último borrador

Una expresión lambda no tendrá una captura predeterminada o una captura simple en su introductor lambda a menos que su ámbito de inclusión más interno sea un ámbito de bloque ([basic.scope.block]) o aparezca dentro de un inicializador de miembro predeterminado y su ámbito de inclusión más interno scope es el ámbito de la clase correspondiente ([basic.scope.class]).

La redacción de C++17 es casi idéntica a la de C++14.

El programa está mal formado y el mensaje de diagnóstico es correcto. Los compiladores que no diagnostican la mala formación (icc, msvc) no se ajustan al estándar.


El programa se puede arreglar simplemente eliminando la captura predeterminada. De todos modos, no puede capturar nada fuera del alcance de un bloque, lo que lo hace inútil, por lo que no está permitido. Se puede acceder a elementos globales como ::g sin capturarlos.

over 4 years ago · Santiago Trujillo Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!