Visual C ++ dan GCCga ko'chirish manba kodlarining qanday tuzilishlari bor?

GCC C ++ standartini Visual C ++ dan ko'ra ko'proq qat'iy amalga oshirishi yaxshi ma'lum. Ochiq so'zlar bilan aytganda, Visual C ++ C ++ standartlariga mos kelmaydi.

Bu esa, avvalo, Visual C ++ bilan ishlab chiquvchilar uchun doimiy bosh og'rig'i bo'lib, ko'chma va kamida GCC bilan tuzilgan kodga muhtoj.

Visual C ++ tilidagi ba'zi xatolar, MSDN nostandart xatti-mavzu da amalda boshqa hujjatsiz holatlar ko'p.

Ushbu postning g'oyasi VC ++ uchun GCC (eng mashhur C ++ kompilyatorlari) ga mos keladigan barcha muvofiqligi muammolarini yozish. Ba'zi kod snippetlari ogohlantirishlarsiz (W4 darajasi) Visual C ++ bilan tuzilganda va GCC bilan (xato yoki ogohlantirish chiqarmay) muammo yuzaga keladi.

Esda tuting, faqat standart C ++ muammolar uchun Microsoft kodi <___ super yoki __ forceinline kabi muayyan til kengaytmasi doirasidan tashqarida.

Tavsiya etilgan tavsif formati:

  • Kod snippetasi (Visual C ++ bilan OK yozildi)
  • GCC xato yoki ogohlantirish ishlab chiqaradi
  • Ikkala kompilyator versiyasi ham ko'paytiriladi
  • Buzuq C ++ standart bayonnomasiga havola (ixtiyoriy, keyinroq qo'shilishi mumkin)
  • Biznes (kodni VC ++ va GCC bilan muvaffaqiyatli tuzilishi uchun qanday o'zgartirish mumkin)
1
@Rost: Xo'sh, bu savol yanada kengroq bo'ladi, chunki u ma'lum bir standartga nisbatan MSVC va GCC emas. Buning o'rniga u ko'p o'lchamli matritsa. Va ochilish shikoyati, MSVC standart quduqqa amal qilmaydi, MSVC qaysi versiyasini va standartning qaysi versiyasini ko'rsatmasdan, shuning uchun da'vo baholashni deyarli mumkin emas.
qo'shib qo'ydi muallif Adrian McCarthy, manba
@Rost: Xo'sh, bu savol yanada kengroq bo'ladi, chunki u ma'lum bir standartga nisbatan MSVC va GCC emas. Buning o'rniga u ko'p o'lchamli matritsa. Va ochilish shikoyati, MSVC standart quduqqa amal qilmaydi, MSVC qaysi versiyasini va standartning qaysi versiyasini ko'rsatmasdan, shuning uchun da'vo baholashni deyarli mumkin emas.
qo'shib qo'ydi muallif Adrian McCarthy, manba
Mening tajribam bu lavozimning ustki qismidagi da'voga ziddir. Ko'p marta men MSccni nostandart ravishda belgilagan kodni qabul qildim. Lekin ikkala kompilyator ham tez harakat qilayotgani sababli farqlarning ro'yxatini tuzish maqsadga muvofiq emas va standart hozirgi kunga nisbatan tezroq yangilanmoqda. MSVC, til xususiyatlariga biroz orqada qolmoqchi, ammo kutubxona xususiyatlariga birmuncha yaqin keladi. Hozircha 100% C ++ 11 mos emas va C ++ 14 standarti endi o'ynaydi. Va keyinchalik u erda yig'latish (LLVM) mavjud. Shunday bo'lsa-da, bu SO uchun juda keng.
qo'shib qo'ydi muallif Adrian McCarthy, manba
Mening tajribam bu lavozimning ustki qismidagi da'voga ziddir. Ko'p marta men MSccni nostandart ravishda belgilagan kodni qabul qildim. Lekin ikkala kompilyator ham tez harakat qilayotgani sababli farqlarning ro'yxatini tuzish maqsadga muvofiq emas va standart hozirgi kunga nisbatan tezroq yangilanmoqda. MSVC, til xususiyatlariga biroz orqada qolmoqchi, ammo kutubxona xususiyatlariga birmuncha yaqin keladi. Hozircha 100% C ++ 11 mos emas va C ++ 14 standarti endi o'ynaydi. Va keyinchalik u erda yig'latish (LLVM) mavjud. Shunday bo'lsa-da, bu SO uchun juda keng.
qo'shib qo'ydi muallif Adrian McCarthy, manba
Standard C ++-ga yopishib olasiz va ehtimol siz bu tuzatishlar oldini olasiz.
qo'shib qo'ydi muallif 101010, manba
@Rost "standart C ++ ga qo'ying": barcha C ++ standartlarini o'qib chiqilgan deb talqin qilinmaydi, balki C ++ standartiga muvofiq kod yozing. Albatta, siz C ++ kompilyatorini yozasiz. Keyin barcha 1300 sahifani o'qishingiz kerak.
qo'shib qo'ydi muallif 101010, manba
@Rost "standart C ++ ga qo'ying": barcha C ++ standartlarini o'qib chiqilgan deb talqin qilinmaydi, balki C ++ standartiga muvofiq kod yozing. Albatta, siz C ++ kompilyatorini yozasiz. Keyin barcha 1300 sahifani o'qishingiz kerak.
qo'shib qo'ydi muallif 101010, manba
Standard C ++-ga yopishib olasiz va ehtimol siz bu tuzatishlar oldini olasiz.
qo'shib qo'ydi muallif 101010, manba
@ Smith_61 mening bayonotimda "ehtimolki eng ko'p" so'zini ko'radi.
qo'shib qo'ydi muallif 101010, manba
@ Smith_61 mening bayonotimda "ehtimolki eng ko'p" so'zini ko'radi.
qo'shib qo'ydi muallif 101010, manba
Bu savol SO ga mos keladigan juda kengdir. Bunga to'liq javob berish uchun, kod parçacıklarını va paydo bo'lgan xato xabari va muqobil echimlarni, har bir standart bo'lmagan mos xususiyat uchun e'lon qilish kerak. Ushbu mavzuga nisbatan adolatni ta'minlash uchun butun veb-sayt yoki wiki kerak bo'ladi.
qo'shib qo'ydi muallif JBentley, manba
Bu savol SO ga mos keladigan juda kengdir. Bunga to'liq javob berish uchun, kod parçacıklarını va paydo bo'lgan xato xabari va muqobil echimlarni, har bir standart bo'lmagan mos xususiyat uchun e'lon qilish kerak. Ushbu mavzuga nisbatan adolatni ta'minlash uchun butun veb-sayt yoki wiki kerak bo'ladi.
qo'shib qo'ydi muallif JBentley, manba
GCC, norasmiy kengaytmalarga ruxsat berishda aybdor. C ++ tomonidan qo'llab-quvvatlanmagan bo'lsa-da, har qanday C99 kodi C ++ fayllariga kirishi mumkin.
qo'shib qo'ydi muallif Ben Voigt, manba
GCC, norasmiy kengaytmalarga ruxsat berishda aybdor. C ++ tomonidan qo'llab-quvvatlanmagan bo'lsa-da, har qanday C99 kodi C ++ fayllariga kirishi mumkin.
qo'shib qo'ydi muallif Ben Voigt, manba
Stack Overflow formatida to'g'ri javob bera olmaydigan savollar mavzu bo'yicha emas. Agar yuzlab javoblar bo'lmasa, o'nlab savollarni so'rayapsiz.
qo'shib qo'ydi muallif Ross Ridge, manba
Stack Overflow formatida to'g'ri javob bera olmaydigan savollar mavzu bo'yicha emas. Agar yuzlab javoblar bo'lmasa, o'nlab savollarni so'rayapsiz.
qo'shib qo'ydi muallif Ross Ridge, manba
@JBentley Bu erda hech qanday muammo yo'q. Ma'lumotni takomillashtirish uchun bir nechta javoblar joylashtirilishi va yangilanishi mumkin. Mukammallikka boshqa yo'l yo'q.
qo'shib qo'ydi muallif Rost, manba
@ 40two standarti taxminan 1300 betlik texnik matnni o'z ichiga oladi. Bunga faqat "yopish" oson emas, shuning uchun oddiy dasturchi uchun imkoniyat yo'q.
qo'shib qo'ydi muallif Rost, manba
@JBentley Bu erda hech qanday muammo yo'q. Ma'lumotni takomillashtirish uchun bir nechta javoblar joylashtirilishi va yangilanishi mumkin. Mukammallikka boshqa yo'l yo'q.
qo'shib qo'ydi muallif Rost, manba
@JBentley Bu erda hech qanday muammo yo'q. Ma'lumotni takomillashtirish uchun bir nechta javoblar joylashtirilishi va yangilanishi mumkin. Mukammallikka boshqa yo'l yo'q.
qo'shib qo'ydi muallif Rost, manba
@ 40two Kodning aslida standartni buzayotgani aniq emas (ayniqsa, agar yurakdan foydalanmasangiz). Ushbu savolning maqsadi bu kabi ishlarni aniqlash va hujjatlashtirishdir.
qo'shib qo'ydi muallif Rost, manba
@ 40two Kodning aslida standartni buzayotgani aniq emas (ayniqsa, agar yurakdan foydalanmasangiz). Ushbu savolning maqsadi bu kabi ishlarni aniqlash va hujjatlashtirishdir.
qo'shib qo'ydi muallif Rost, manba
@AdrianMcCarthy Aslida kompilyatorlar va standartlarning qanchalik tez harakat qilayotgani muhim emas. Haqiqiy dunyo juda ham konservativ va jang maydonidan uzoqroq. Kompaniyalarning o'nlab turlari ishlab chiqarishda hali ham C ++ 11 foydalanmaydi. Va VS2008 va GCC 4.1.2 ni qo'llab-quvvatlash hali ham kam hollarda.
qo'shib qo'ydi muallif Rost, manba
@AdrianMcCarthy Aslida kompilyatorlar va standartlarning qanchalik tez harakat qilayotgani muhim emas. Haqiqiy dunyo juda ham konservativ va jang maydonidan uzoqroq. Kompaniyalarning o'nlab turlari ishlab chiqarishda hali ham C ++ 11 foydalanmaydi. Va VS2008 va GCC 4.1.2 ni qo'llab-quvvatlash hali ham kam hollarda.
qo'shib qo'ydi muallif Rost, manba
@AdrianMcCarthy Aslida kompilyatorlar va standartlarning qanchalik tez harakat qilayotgani muhim emas. Haqiqiy dunyo juda ham konservativ va jang maydonidan uzoqroq. Kompaniyalarning o'nlab turlari ishlab chiqarishda hali ham C ++ 11 foydalanmaydi. Va VS2008 va GCC 4.1.2 ni qo'llab-quvvatlash hali ham kam hollarda.
qo'shib qo'ydi muallif Rost, manba
@ 40two standarti taxminan 1300 betlik texnik matnni o'z ichiga oladi. Bunga faqat "yopish" oson emas, shuning uchun oddiy dasturchi uchun imkoniyat yo'q.
qo'shib qo'ydi muallif Rost, manba
@ 40two hatto standart C ++ ga yopishish ham yaxshi ishlamaydi. OP'in ta'kidlashicha, Visual Studio standartni bajarishda juda yomon, va har ikkalasida ham ishlaydigan kod yaratish haqiqiy standartning cheklangan to'plamidir. Bu yoki "#ifdef MSVC shamlardan
qo'shib qo'ydi muallif Smith_61, manba
@ 40two hatto standart C ++ ga yopishish ham yaxshi ishlamaydi. OP'in ta'kidlashicha, Visual Studio standartni bajarishda juda yomon, va har ikkalasida ham ishlaydigan kod yaratish haqiqiy standartning cheklangan to'plamidir. Bu yoki "#ifdef MSVC shamlardan
qo'shib qo'ydi muallif Smith_61, manba

6 javoblar

Bu juda keng savol, lekin men aynan shu narsalarga qo'shilaman:

Deklaratsiyalashning noto'g'ri nuqtasi:

#include 

struct S {
  S(int) { std::cout << "Incorrect\n"; }
  S(S const &) { std::cout << "Correct\n"; }
};

int s;

int main() {
  S s(s);
}

Chiqish "to'g'ri" bo'lishi kerak, ammo Visual Studio (barcha versiyalar) chiqishi "noto'g'ri".


Replikatsiya topshirig'ining noto'g'ri ishlab chiqarilishi va nusxa ko'chirishning boshlanishi:

#include 

struct B {
    B &operator = (B &) { std::cout << "Correct\n"; return *this; }
    template
    B &operator = (T &) { std::cout << "Incorrect\n"; return *this; }
};

struct D : B {};

int main() {
    D d;
    d = d;
}

Bu Visual Studio 2012 yilda o'rnatildi deb o'ylayman. 2012 yilgacha VS chiqishi "noto'g'ri" edi.


Ikki bosqichli ism qidirish:

#include 

static void foo(long) {
  std::cout << "Correct\n";
}

template
void bar(T t) {
  foo(t);
}

static void foo(int) {
  std::cout << "Incorrect\n";
}

int main() {
  bar(1);
}

Chiqish "to'g'ri" bo'lishi kerak, ammo Visual Studio'ning (hozirgacha barcha versiyalar) chiqishi "noto'g'ri".


Shu bilan bir qatorda belgilar ishlamaydi:

int main() <% %>

Ushbu dastur kompilyatsiya va ishga tushirilishi kerak, ammo Visual Studio versiyasi muvaffaqiyatli tuzilmaydi.


for-loop boshlang'ich qoidasi ichida foydalanuvchi belgilangan ta'rifi belgilari:

int main() {
  for (struct {int a;} a = {0}; a.a < 10; ++(a.a)) {

  }
}

Bu qonuniy, lekin VS bunga ruxsat bermaydi.


Bularning barchasi kompilyatsiya va gcc va clang ostida to'g'ri ishlaydi. Gcc, ikki bosqichli qidirish bilan bog'liq muammolarga duch kelgan, ammo hozircha bir muncha vaqt emas.

3
qo'shib qo'ydi

Bu juda keng savol, lekin men aynan shu narsalarga qo'shilaman:

Deklaratsiyalashning noto'g'ri nuqtasi:

#include 

struct S {
  S(int) { std::cout << "Incorrect\n"; }
  S(S const &) { std::cout << "Correct\n"; }
};

int s;

int main() {
  S s(s);
}

Chiqish "to'g'ri" bo'lishi kerak, ammo Visual Studio (barcha versiyalar) chiqishi "noto'g'ri".


Replikatsiya topshirig'ining noto'g'ri ishlab chiqarilishi va nusxa ko'chirishning boshlanishi:

#include 

struct B {
    B &operator = (B &) { std::cout << "Correct\n"; return *this; }
    template
    B &operator = (T &) { std::cout << "Incorrect\n"; return *this; }
};

struct D : B {};

int main() {
    D d;
    d = d;
}

Bu Visual Studio 2012 yilda o'rnatildi deb o'ylayman. 2012 yilgacha VS chiqishi "noto'g'ri" edi.


Ikki bosqichli ism qidirish:

#include 

static void foo(long) {
  std::cout << "Correct\n";
}

template
void bar(T t) {
  foo(t);
}

static void foo(int) {
  std::cout << "Incorrect\n";
}

int main() {
  bar(1);
}

Chiqish "to'g'ri" bo'lishi kerak, ammo Visual Studio'ning (hozirgacha barcha versiyalar) chiqishi "noto'g'ri".


Shu bilan bir qatorda belgilar ishlamaydi:

int main() <% %>

Ushbu dastur kompilyatsiya va ishga tushirilishi kerak, ammo Visual Studio versiyasi muvaffaqiyatli tuzilmaydi.


for-loop boshlang'ich qoidasi ichida foydalanuvchi belgilangan ta'rifi belgilari:

int main() {
  for (struct {int a;} a = {0}; a.a < 10; ++(a.a)) {

  }
}

Bu qonuniy, lekin VS bunga ruxsat bermaydi.


Bularning barchasi kompilyatsiya va gcc va clang ostida to'g'ri ishlaydi. Gcc, ikki bosqichli qidirish bilan bog'liq muammolarga duch kelgan, ammo hozircha bir muncha vaqt emas.

3
qo'shib qo'ydi

Bu juda keng savol, lekin men aynan shu narsalarga qo'shilaman:

Deklaratsiyalashning noto'g'ri nuqtasi:

#include 

struct S {
  S(int) { std::cout << "Incorrect\n"; }
  S(S const &) { std::cout << "Correct\n"; }
};

int s;

int main() {
  S s(s);
}

Chiqish "to'g'ri" bo'lishi kerak, ammo Visual Studio (barcha versiyalar) chiqishi "noto'g'ri".


Replikatsiya topshirig'ining noto'g'ri ishlab chiqarilishi va nusxa ko'chirishning boshlanishi:

#include 

struct B {
    B &operator = (B &) { std::cout << "Correct\n"; return *this; }
    template
    B &operator = (T &) { std::cout << "Incorrect\n"; return *this; }
};

struct D : B {};

int main() {
    D d;
    d = d;
}

Bu Visual Studio 2012 yilda o'rnatildi deb o'ylayman. 2012 yilgacha VS chiqishi "noto'g'ri" edi.


Ikki bosqichli ism qidirish:

#include 

static void foo(long) {
  std::cout << "Correct\n";
}

template
void bar(T t) {
  foo(t);
}

static void foo(int) {
  std::cout << "Incorrect\n";
}

int main() {
  bar(1);
}

Chiqish "to'g'ri" bo'lishi kerak, ammo Visual Studio'ning (hozirgacha barcha versiyalar) chiqishi "noto'g'ri".


Shu bilan bir qatorda belgilar ishlamaydi:

int main() <% %>

Ushbu dastur kompilyatsiya va ishga tushirilishi kerak, ammo Visual Studio versiyasi muvaffaqiyatli tuzilmaydi.


for-loop boshlang'ich qoidasi ichida foydalanuvchi belgilangan ta'rifi belgilari:

int main() {
  for (struct {int a;} a = {0}; a.a < 10; ++(a.a)) {

  }
}

Bu qonuniy, lekin VS bunga ruxsat bermaydi.


Bularning barchasi kompilyatsiya va gcc va clang ostida to'g'ri ishlaydi. Gcc, ikki bosqichli qidirish bilan bog'liq muammolarga duch kelgan, ammo hozircha bir muncha vaqt emas.

3
qo'shib qo'ydi

Code snippet, VC ++ 2013 bilan OK yozildi:

struct X
{
   template  struct Z {};

   template <> struct Z {};//Source of problem
};

GCC error produced (4.7.2): error: explicit specialization in non-namespace scope

Violated standard clause: 14.7.3 Explicit specialization, p.2 - An explicit specialization shall be declared in a namespace enclosing the specialized template.

Solution: use partial specialization instead of explicit one:

struct X
{
    template  struct Z {};

    template  struct Z {};
};

Yoki iloji bo'lsa, uni nom maydoni kengaytmasi bilan bog'lang.

struct X
{
    template  struct Z {};
};

template <> struct X::Z {};
1
qo'shib qo'ydi

Code snippet, VC ++ 2013 bilan OK yozildi:

struct X
{
   template  struct Z {};

   template <> struct Z {};//Source of problem
};

GCC error produced (4.7.2): error: explicit specialization in non-namespace scope

Violated standard clause: 14.7.3 Explicit specialization, p.2 - An explicit specialization shall be declared in a namespace enclosing the specialized template.

Solution: use partial specialization instead of explicit one:

struct X
{
    template  struct Z {};

    template  struct Z {};
};

Yoki iloji bo'lsa, uni nom maydoni kengaytmasi bilan bog'lang.

struct X
{
    template  struct Z {};
};

template <> struct X::Z {};
1
qo'shib qo'ydi

Code snippet, VC ++ 2013 bilan OK yozildi:

struct X
{
   template  struct Z {};

   template <> struct Z {};//Source of problem
};

GCC error produced (4.7.2): error: explicit specialization in non-namespace scope

Violated standard clause: 14.7.3 Explicit specialization, p.2 - An explicit specialization shall be declared in a namespace enclosing the specialized template.

Solution: use partial specialization instead of explicit one:

struct X
{
    template  struct Z {};

    template  struct Z {};
};

Yoki iloji bo'lsa, uni nom maydoni kengaytmasi bilan bog'lang.

struct X
{
    template  struct Z {};
};

template <> struct X::Z {};
1
qo'shib qo'ydi