Bu C ++ işlevinin adı nedir?


82

Bazı C ++ kodu yazıyordum ve yanlışlıkla bir işlevin adını atladım WSASocket. Ancak, derleyicim bir hata oluşturmadı ve my'ı SOCKETgeçerli bir soket yerine tam sayı değeri 1 ile ilişkilendirdi .

Söz konusu kod şöyle görünmeliydi:

this->listener = WSASocket(address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);

Ama bunun yerine şuna benziyordu:

this->listener = (address->ai_family, address->ai_socktype, address->ai_protocol, NULL, NULL, WSA_FLAG_OVERLAPPED);

Diğer dillerden gelince, bu bir tür anonim tipte olabilir gibi görünüyor . Gerçekten bir özellik olması durumunda, özelliğin adı nedir?

Amacı nedir?

Nereden başlayacağınızı bilmediğinizde onu aramak zordur.


3
+1, bir pub testi için güzel bir soru (veya zeka oyunları konusunda iyi olan kişileri işe almaktan hoşlanan firmalar için korkunç bir röportaj sorusu).
Bathsheba

8
Virgül operatörüyle ilgili Wikipedia makalesine bağlantı . FWIW, yaygın kullanımlardan biri, (int i = 0, j = 0; i <10; ++ i, --j) ... ``for, ala
Tony Delroy

1
@ MichaelJ.Gray Teknik olarak yanılıyorsunuz. Davranışın üzerine yazmak değildir. Hayal edin: i=0;j=0;x=i++,j=6;x ve j 6 olur ve ben yine de 1. Eğer i ++ 'nın davranışı üzerine yazılırsa , 0 olarak kalır. Ancak her ifade çağrılır ve ,sadece tüm uzantılara ulaştıktan sonra atılır ve bir sonraki sözde sıra noktası çağrılır. Yani =ilki, sondan sonraki bölümü atar, ,ancak her nokta çağrılır. Her neyse: Derleyicinizin sizi neden işlev bildiriminin yeniden tanımlanması konusunda
uyarmadığını

5
Eğer açık uyarılarla uygun bir derleyici, kullanırsanız, örneğin, tehlikeli kod hakkında uyarır gccve g++ile -Wallopsiyon söz hakkından:warning: left-hand operand of comma expression has no effect [-Wunused-value]
Sam Watkins

3
Bu yüzden, bence bu sorunun en iyi cevabı "her zaman uyarıları etkinleştir" - o zaman derleyicinin kendisi bir hata olduğunu açıklayacak ve ne yaptığınızı size söyleyecektir; ve bu cevap sizin için başka birçok sorunu da çözecektir.
Sam Watkins

Yanıtlar:


151

Virgül operatörü † sol tarafı değerlendirir, değerini atar ve sonuç olarak sağ tarafı verir. WSA_FLAG_OVERLAPPED1'dir ve bu ifadenin sonucudur; diğer tüm değerler atılır. Hiç bir soket oluşturulmaz.


† Aşırı yüklenmedikçe. Evet, aşırı yüklenebilir. Hayır, aşırı yüklememelisin. Hemen şimdi klavyeden uzaklaşın!


9
+1, boost spirit virgül operatörünü çok etkili bir şekilde aşırı yükler, ancak bu kuralın çok yalnız bir istisnasıdır: bunu yapmayın .
Bathsheba

2
@Bathsheba Boost.Assign virgül operatörünü de aşırı yüklüyor, ancak bunu C ++ 11'den beri kim kullanıyor?
rubenvb

39
Ama virgülün ne kadar korkunç olabileceğine dair en iyi açıklamaya sahiptin. Bağışlamayan ve alay konusu olan bu kod, davranışlarından utanmadan bana bakarken birkaç dakika boyunca kodumu rahatsız etti.
Michael J. Gray


1
@ R.MartinhoFernandes - Eigen ayrıca virgül operatörünü çok etkili bir şekilde aşırı yükler. Bazı örnek kullanımlar için bu SE sorusuna bakın .
David Hammen

22

Virgül operatörü Kodunuzun duygusu yapıyor.

this->listener = WSA_FLAG_OVERLAPPED;Sözdizimsel olarak geçerli olanı etkin bir şekilde ayarlıyorsunuz .


3
Yalnızca sözdizimsel olarak geçerli değil, Windows API tür güvenli olmadığından, aynı zamanda geçerli bir dönüşümdür.
MSalters

5
@MSalters, POSIX bu açıdan çok daha iyi değil
chbaker0

1
Bu nedenle tek bir bağımsız değişkenle çağrılabilen kurucuların açık olması gerekir , o zaman bir derleyici hatası oluşur ve geliştiricinin bu tuhaf yapıya ikinci kez bakma şansı olur.
Matthieu M.

@MSalters Eh, SOCKETbir typedef unsigned intve WSA_FLAG_OVERLAPPEDbir olduğunu intdeğişmezi. Bunun SOCKETeşanlamlısı olsaydı, intbir dönüşüm bile olmazdı .
Joker_vD

1
@Joker_vD: Gerçekten. Bunu bir daktilo etselerdi struct __socket*, daha az hatamız olurdu. Ama orada "bilen" SOCKETnin integral olduğu çok fazla kod var .
MSalters

21

Derleyici, her sıra noktasını sırayla parantez içinde değerlendirir ve sonuç, ifadedeki son WSA_FLAG_OVERLAPPEDifadedir.

Virgül operatörü ,, C ++ 'da bir sıra noktasıdır. Virgülün solundaki ifade, sağdaki ifadeden önce tam olarak değerlendirilir. Sonuç her zaman sağdaki değerdir. Formun bir ifadesine (x1, x2, x3, ..., xn) sahip olduğunuzda, ifadenin sonucu her zaman olur xn.


Açıklamanızı oraya ekledikten sonra, daha mantıklı geliyor. Başlangıçta sıra noktası sorununun alaka düzeyini tam olarak anlamadım.
Michael J. Gray
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.