国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

直擊VS2010中的std::tr1 bind庫(kù)BUG

開發(fā) 后端
今天我們將看到的是Visual Studio 2010中一個(gè)BUG被捉住的過程。也就是std::tr1 bind庫(kù)BUG。

前兩天發(fā)現(xiàn)了VC2010 tr1庫(kù)中bind實(shí)現(xiàn)的一個(gè)bug,當(dāng)時(shí)只是作了記錄,沒有詳細(xì)分析.但作為一個(gè)QA,不找出問題所在實(shí)在不算稱職,于是就有了這篇捉蟲記.

閑言少敘,書歸正傳,tr1庫(kù)就不多作介紹了,有興趣的同學(xué)可以去 wikipedia上看.bind,顧名思義,就是把參數(shù)與函數(shù)綁定,以利于我們進(jìn)行函數(shù)式編程,是從boost的bind庫(kù)引入的,對(duì)bind不是很了解的可以看陳碩同學(xué)的這篇

以boost::function和boost:bind取代虛函數(shù)

假定筆者是 VC2010的QA,在做bind的功能測(cè)試,開始用gtest寫test case, (筆者一般用gtest作為C++測(cè)試框架,就寫到文章中了,但ms肯定不會(huì)用啦.筆者不在ms,請(qǐng)勿對(duì)號(hào)入座)

先寫幾個(gè)簡(jiǎn)單的函數(shù)供測(cè)試之用. 

  1. int Add(int left, int right)  
  2. {  
  3. return left + right;  
  4. }  
  5. int Sub(int left, int right)  
  6. {  
  7. return left - right;  
  8. }  
  9. int Mul(int left, int right)  
  10. {  
  11. return left * right;  

再寫測(cè)試用例.先是幾個(gè)簡(jiǎn)單的

1 把值綁定到函數(shù)指針

  1. TEST(Bind, FundPtr_Values)   
  2. {   
  3. auto f0 = std::tr1::bind(Sub, 5, 3);   
  4. ASSERT_EQ(2, f0());   

2 把值綁定到仿函數(shù)

  1. TEST(Bind, Functor_Values)   
  2. {   
  3. auto f0 = std::tr1::bind(std::minus<int>(), 6, 4);   
  4. ASSERT_EQ(2, f0());   

3 把占位符綁定到函數(shù)指針

  1. TEST(Bind, FuncPtr_Placeholder)  
  2. {  
  3. auto f0 = std::tr1::bind(Sub, std::tr1::placeholders::_1, 8);  
  4. ASSERT_EQ(12, f0(20));  

4 將占位符綁定到仿函數(shù)

  1. TEST(Bind, Functor_Placeholder)  
  2. {  
  3. auto f0 = std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_2, std::placeholders::_1);  
  4. ASSERT_EQ(12, f0(8, 20));  

運(yùn)行測(cè)試

  1. testing::InitGoogleTest(&argc, argv);  
  2. int ret = RUN_ALL_TESTS(); 

一切OK.

來個(gè)復(fù)雜的,將bind返回結(jié)果再bind到函數(shù),用于進(jìn)行高階函數(shù)演算.

組合函數(shù)指針

  1. TEST(Bind, SquareDiff_FuncPtr)  
  2. {  
  3. auto f0 = std::tr1::bind(Mul,   
  4. std::tr1::bind(Add, std::tr1::placeholders::_1, std::tr1::placeholders::_2),  
  5. std::tr1::bind(Sub, std::tr1::placeholders::_1, std::tr1::placeholders::_2));  
  6. ASSERT_EQ(16, f0(5, 3));  

運(yùn)行,一切OK,

再來一個(gè)仿函數(shù)版本

組合仿函數(shù)

  1. TEST(Bind, Squarediff_Functorptr)  
  2. {  
  3. auto f0 = std::tr1::bind(std::multiplies<int>(),  
  4. std::tr1::bind(std::plus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2),  
  5. std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2));  
  6. ASSERT_EQ(16, f0(5, 3));  

編譯 , wow,這是啥啊

Error    1    error C2664: 'int std::multiplies<_Ty>::operator ()(const _Ty &,const _Ty &) const' : cannot convert parameter 1 from 'std::tr1::_Bind_fty<_Fty,_Ret,_BindN>' to 'const int &'    c:\program files\microsoft visual studio 10.0\vc\include\xxcallobj    13    1    boostDemo 

發(fā)現(xiàn)問題了, 偶兩眼開始放光.

現(xiàn)在就開bug么,不,太早了,總得指明問題在哪兒吧.是編譯器還是tr1庫(kù)實(shí)現(xiàn)的問題?怎么辦?拿另一個(gè)庫(kù)boost試試,正常

通過就是tr1的問題了

  1. TEST(Bind, SquareDiff_BoostFunctor)  
  2. {  
  3. auto f0 = boost::bind(std::multiplies<int>(),  
  4. boost::bind(std::plus<int>(), _1, _2),  
  5. boost::bind(std::minus<int>(),_1, _2));  
  6. ASSERT_EQ(16, f0(5, 3));  

編譯運(yùn)行,一切正常.

現(xiàn)在可以肯定是tr1庫(kù)的問題么?還不能.也許對(duì)仿函數(shù)綁定是boost的擴(kuò)展而tr1準(zhǔn)標(biāo)準(zhǔn)并不支持呢?

打開標(biāo)準(zhǔn),看bind參數(shù)的說明 template<class F, class T1, class T2, ...., class TN>

unspecified bind(F f, T1 t1, T2 t2, ..., TN tN);

1 Requires: F and Ti shall be CopyConstructible. INVOKE (f, w1, w2, ..., wN) ([3.3]) shall be a valid expression

for some values w1, w2, ..., wN.

2 Returns: A forwarding call wrapper g with a weak result type ([3.3]). The effect of g(u1, u2, ..., uM) shall

be INVOKE (f, v1, v2, ..., vN, result_of<F cv (V1, V2, ..., VN)>::type), where cv represents

the cv-qualifiers of g and the values and types of the bound arguments v1, v2, ..., vN are determined as

specified below.

template<class R, class F, class T1, class T2, ...., class TN>

unspecified bind(F f, T1 t1, T2 t2, ..., TN tN);

3 Requires: F and Ti shall be CopyConstructible. INVOKE (f, w1, w2, ..., wN) shall be a valid expression for

some values w1, w2, ..., wN.

4 Returns: A forwarding call wrapper g with a nested type result_type defined as a synonym for R. The effect of

g(u1, u2, ..., uM) shall be INVOKE (f, v1, v2, ..., vN, R), where the values and types of the bound

arguments v1, v2, ..., vN are determined as specified below.

5 The values of the bound arguments v1, v2, ..., vN and their corresponding types V1, V2, ..., VN depend on

the type of the corresponding argument ti of type Ti in the call to bind and the cv-qualifiers cv of the call wrapper g as

follows:

— if ti is of type reference_wrapper<T> the argument is ti.get() and its type Vi is T&;

— if the value of std::tr1::is_bind_expression<Ti>::value is true the argument is ti(u1, u2, ...,

uM) and its type Vi is result_of<Ti cv (U1&, U2&, ..., UM&)>::type;

— if the value j of std::tr1::is_placeholder<Ti>::value is not zero the argument is uj and its type Vi is

Uj&;

— otherwise the value is ti and its type Vi is Ti cv &. 

這里參數(shù)t,v,W來回出現(xiàn),挺繞的,書讀百遍,其義自現(xiàn) f為要綁定的函數(shù),其參數(shù)為 v1,v2,…,vN,類型為V1,V2,…,VN

bind 函數(shù)參數(shù)為t1, t2, …,tN,類型為T1,T2,…,TN

g 為bind的返回值,參數(shù)為參數(shù)為u1, u2,…uM,類型為U1, U2,…,UM.

g(u1, u2,…uM)會(huì)被轉(zhuǎn)發(fā)給f,轉(zhuǎn)發(fā)效果相當(dāng)于f(v1, v2, …,vN)

vi 如下確定

如果對(duì)應(yīng)bind函數(shù)參數(shù)ti類型為reference_wrapper<T>, 則vi為ti.get(),類型為T&
如果std::tr1::is_bind_expression<Ti>::value為true,即ti是bind的返回值,則vi為ti(u1,u2,…uM),類型為result_of<Ti cv(U1&,U2&,…,UM)>::type
如果std::tr1::is_placeholder<Ti>::value非0,則參數(shù)vi為uj,類型為 Uj&
否則vi值為ti,類型為Ti cv& 

現(xiàn)在就很明了了,一個(gè)bind的返回值r1可以作為另一個(gè)bind的參數(shù)a1,在轉(zhuǎn)發(fā)時(shí)轉(zhuǎn)發(fā)的是r1(u1, u2,…,uM),即測(cè)試的代碼是符合標(biāo)準(zhǔn)的.那為什么通不過呢?再加上兩個(gè)測(cè)試,看看bind的返回值類型究竟能否讓 is_bind_expression<T>::value為true

is_bind_expression測(cè)試

  1. template<class T>  
  2. bool IsBindResult(const T& v)  
  3. {  
  4. return std::tr1::is_bind_expression<T>::value;  
  5. }  
  6. TEST(IsBindResult, BindFuncPtr)  
  7. {  
  8. ASSERT_TRUE(IsBindResult(std::tr1::bind(Add, std::tr1::placeholders::_1, 2)));  
  9. }  
  10. TEST(IsBindResult, BindFunctor)  
  11. {  
  12. ASSERT_TRUE(IsBindResult(std::tr1::bind(std::plus<int>(), std::tr1::placeholders::_1, 2)));  

編譯,運(yùn)行

clip_image001

結(jié)果再次讓偶大躍眼鏡,居然bind的返回值沒能通過is_bind_expression的測(cè)試,怎么回事,打開is_bind_expression 的源碼來看

is_bind_expression定義

  1. template<class _Tx>  
  2. struct is_bind_expression  
  3. {   
  4. static const bool value = false;  
  5. };  
  6. template<class _Result_type,  
  7. class _Ret,  
  8. class _BindN>  
  9. struct is_bind_expression<  
  10. _Bind<_Result_type, _Ret, _BindN> >  
  11. {   
  12. static const bool value = true;  
  13. }; 

這里對(duì)模板作了一個(gè)特化,如果bind的模板參數(shù)是 _Bind<_Result_type, _Ret, _BindN>類型,則value為true,否則false.

看上去很美,沒問題,那為什么測(cè)試會(huì)失敗?難道bind(Add,…)返回的是_Bind類型而 bind(plus<int>(),…)返回的不是?接著看bind實(shí)現(xiàn):

函數(shù)指針版

bind到函數(shù)指針的返回類型

  1. template<class _Rx  
  2. _C_CLASS_FARG0  
  3. _C_CLASS_ARG0> inline  
  4. _Bind<_Rx,  
  5. _Rx,  
  6. _BINDN<_Callable_fun<_Rx(__cdecl * const)(_FARG0_FARG1)> _C_ARG0_ARG1> >  
  7. bind(_Rx(__cdecl * const _Val)(_FARG0_FARG1) _C_ARG0_A0)  
  8. // bind to pointer to function  
  9. typedef _Callable_fun<_Rx(__cdecl * const)(_FARG0_FARG1)> _Callable;  
  10. typedef _BINDN<_Callable _C_ARG0_ARG1> _MyBind;  
  11. return (_Bind<_Rx, _Rx, _MyBind>(_MyBind(_Val _C_A0_A1)));  

返回的的確是_Bind類型,

仿函數(shù)版

bind到仿函數(shù)的返回類型

  1. template<class _Fty  
  2. _C_CLASS_ARG0> inline  
  3. _Bind_fty<_Fty,  
  4. _Notforced,  
  5. _BINDN<_Callable_obj<_Fty> _C_ARG0_ARG1> >  
  6. bind(_Fty _Val _C_ARG0_A0)  
  7. // bind to UDT  
  8. typedef _BINDN<_Callable_obj<_Fty> _C_ARG0_ARG1> _MyBind;  
  9. return (_Bind_fty<_Fty, _Notforced, _MyBind>(_MyBind(_Val _C_A0_A1)));  

返回的卻是_Bind_fty類型, 難道_Bind_fty不是_Bind類型導(dǎo)致is_bind_expression返回false?接著看定義

_BindN和_Bind_fty的定義

  1. template<class _Ret,  
  2. class _BindN>  
  3. class _Bind<_Notforced, _Ret, _BindN>  
  4. public _Bind_base<_Ret, _BindN>  
  5. {   
  6. public:  
  7. _Bind(_BindN _B0)  
  8. : _Bind_base<_Ret, _BindN>(_B0)  
  9. {   
  10. }  
  11. };  
  12. template<class _Fty,  
  13. class _Ret,  
  14. class _BindN>  
  15. class _Bind_fty  
  16. public _Wrap_result_type<(sizeof (::std:: tr1::_Has_result_type((_Fty *)0)) == sizeof (::std:: tr1::_Yes)), _Fty>,  
  17. public _Bind_base<_Ret, _BindN>  
  18. {   
  19. public:  
  20. _Bind_fty(_BindN _B0)  
  21. : _Bind_base<_Ret, _BindN>(_B0)  
  22. {   
  23. }  
  24. }; 

果然如此,真相大白.is_bind_expression不認(rèn)為 bind(functor…)是bind表達(dá)式,故會(huì)直接將其作為類型為_Bind_fty的參數(shù)轉(zhuǎn)發(fā)為 logical_and,導(dǎo)致編譯出錯(cuò).

找到錯(cuò)誤原因,可以開bug了 Title: std::tr1::bind can't bind a functor as an argument to another functor

How found: manual test

Build version:VC 1010 01019-532-2002102-70993

OS: Windows XP

Repro steps:

Run following code:

出錯(cuò)代碼

  1. TEST(Bind, Squarediff_Functorptr)  
  2. {  
  3. auto f0 = std::tr1::bind(std::multiplies<int>(),  
  4. std::tr1::bind(std::plus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2),  
  5. std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2));  
  6. ASSERT_EQ(16, f0(5, 3));  
  7. }  
  8. Expected:  
  9. Code got compiled and test passed. See n1836  
  10. Result:  
  11. Build break 
  12.  
  13. Note:  
  14.  
  15. The result of std::tr1::bind(std::minus<int>(), std::tr1::placeholders::_1, std::tr1::placeholders::_2) 
  16. is of type _Bind_fty, which will make is_bind_expression<_Bind_fty>::value = false. Suggestion: modify the 
  17. return type of bind or change is_bind_expression to make is_bind_expression<_Bind_fty>::value to be true.  

提交bug, Ok.

結(jié)束了么?還沒有,需要編寫一個(gè)測(cè)試來驗(yàn)證這個(gè)問題并加到測(cè)試列表里去,可是直接寫會(huì)導(dǎo)致編譯出錯(cuò),怎么辦呢?

有辦法,

將如下代碼保存到一個(gè)文件去

測(cè)試代碼

  1. #include <iostream>  
  2. #include <conio.h>   
  3. #include <tchar.h>  
  4. int main()   
  5. {   
  6. auto f0 = std::tr1::bind(std::multiplies&lt;int&gt;(),   
  7. std::tr1::bind(std::plus&lt;int&gt;(), std::tr1::placeholders::_1, std::tr1::placeholders::_2),   
  8. std::tr1::bind(std::minus&lt;int&gt;(), std::tr1::placeholders::_1, std::tr1::placeholders::_2));   
  9. return f0(5, 3);   

調(diào)用cl編譯這個(gè)文件,如果能得到一個(gè)可執(zhí)行程序并且執(zhí)行后返回16則測(cè)試通過,否則測(cè)試失敗.

代碼就不在這里列舉了.

寫完測(cè)試,添加到daily build的test list中去,什么時(shí)候問題解決了從測(cè)試結(jié)果上就能看出來了.

1 文中寫的找bug的過程是直線式的邏輯,思路很清晰,實(shí)際我在跟代碼的時(shí)候就像在一個(gè)迷宮里打轉(zhuǎn),只看見出了錯(cuò)誤,不知道什么地方錯(cuò)了,只好用各種手段, 想先找出bind在綁定函數(shù)指針時(shí)究竟干了什么,再來推理為什么綁定仿函數(shù)會(huì)出錯(cuò),根本不是象文中寫的那 樣直接推斷到is_bind_expression的問題.

VC2010里tr1庫(kù)的實(shí)現(xiàn)實(shí)在不好閱讀,滿篇全是宏,連函數(shù)調(diào)用傳了幾個(gè)參數(shù)都搞不清楚,我只好先用/E選項(xiàng)把預(yù)編譯的文件輸出出來,在跟蹤代碼時(shí)一邊看預(yù)處理后的代碼一邊看匯編,無(wú)論哪個(gè)都比tr1自己的源代碼好讀.

不過這一番跟蹤下來收獲倒也頗豐,

1) 基本清楚了bind的實(shí)現(xiàn),可以另外寫篇博客來談

2) 明白了RVO(返回值優(yōu)化)的原理.在跟蹤bind匯編代碼時(shí)時(shí)發(fā)現(xiàn)只要三個(gè)參數(shù),卻push了四個(gè),調(diào)用完成后也是ret 10返回,跟了下去才發(fā)現(xiàn)是做的RVO

2 文中用到了ASSERT宏進(jìn)行測(cè)試,也算是對(duì)前些天對(duì)我這篇金山衛(wèi)士代碼批評(píng)評(píng)論里大家對(duì)ASSERT質(zhì)疑的一個(gè)回應(yīng)吧.c++庫(kù)里的assert的作用是及時(shí)發(fā)現(xiàn)錯(cuò)誤反饋給程序員, 會(huì)打斷程序執(zhí)行,而測(cè)試框架里的ASSERT則是斷言測(cè)試是否符合預(yù)期,把結(jié)果傳遞給測(cè)試框架,再由測(cè)試框架記錄后反饋給程序員.我原來以為在那個(gè)上下文都是測(cè)試情況下assert的語(yǔ)義應(yīng)當(dāng)不言自明的是指后者,沒想到還是有很多讀者誤以為是c++庫(kù)里的assert.這是我沒有把話說清楚,假定自己知道的受眾也知道,忽略了背景的區(qū)別帶來的對(duì)同一個(gè)名詞不同的理解,是我經(jīng)常犯的一個(gè)錯(cuò)誤,要努力改正.

3 QA除了寫測(cè)試用例,用工具和腳本進(jìn)行測(cè)試外還可以在項(xiàng)目過程中參與更多.一個(gè)好的QA應(yīng)當(dāng)有不弱于Dev的編碼能力, 有能力復(fù)查Dev設(shè)計(jì)和編碼,直接從中發(fā)現(xiàn)問題,以及在測(cè)試中發(fā)現(xiàn)問題時(shí)有能力定位bug源頭并給出參考解決方案.QA還要有縝密的思維和想象能力,對(duì)邊界條件、各種邏輯組合和極端情況能去構(gòu)造和評(píng)估其對(duì)功能的影響,因?yàn)镈ev一般習(xí)慣于正常情況下的邏輯,邊界情況雖然也會(huì)考慮,但還是不會(huì)有QA想的全面.遺憾的是目前國(guó)內(nèi)開發(fā)團(tuán)隊(duì)中這樣的QA還是比較少見.

原文鏈接:http://www.cnblogs.com/MichaelPeng/archive/2010/12/27/ABugReportOnVC2010_std_tr1_bind.html

【編輯推薦】 

  1. Visual Studio自定義調(diào)整窗體的兩個(gè)小技巧
  2. Visual Studio 2010中關(guān)于C#的幾點(diǎn)改進(jìn)
  3. Visual Studio 2010及.Net 4新功能一覽
  4. 提高效率 用好Visual Studio 2010自定義代碼段
     

 

責(zé)任編輯:彭凡 來源: 博客園
相關(guān)推薦

2011-08-16 14:50:05

CMFCToolBarVS2010

2009-12-02 14:19:09

VS 2010產(chǎn)品

2011-06-23 10:16:55

VS2010 QT 4.7.2 QT

2009-11-11 11:29:37

VS2010 Auto

2009-12-11 15:13:15

VS 2010驅(qū)動(dòng)

2009-07-28 10:00:47

VS2010 beta

2010-01-14 10:56:43

Visual C++

2009-12-15 17:55:54

VS2010 Ulti

2009-12-11 14:16:11

VS2010 Ulti

2009-12-15 17:42:29

2011-01-18 08:55:20

IntelliTracVS2010

2009-12-02 14:05:17

VS2010程序

2010-04-18 19:51:03

VS2010

2009-12-18 10:24:28

VS 2010代碼

2010-05-06 17:46:47

2009-06-10 22:41:47

Visual StudVS2010ASP.NET MVC

2009-05-26 10:01:51

Visual StudVisual C++C++0x

2011-06-23 09:54:00

VS2010 Qt 4.7.2 Qt

2009-05-21 14:42:09

.NET 4.0VS2010Visual Stud

2010-12-02 23:08:44

Tech?Ed 201Dynamic Mem
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

在线激情av| 亚洲国内欧美| 日韩一区二区免费视频| 亚州色图欧美色图| 国产精品女同互慰在线看| 日本老太婆做爰视频| aa国产精品| 国产一区二区三区四区五区加勒比| 亚洲成a人片77777在线播放 | 久草精品视频| 欧美日本高清一区| 国产一区 二区| 欧美高清videos高潮hd| 电影一区中文字幕| 欧美日韩国产成人在线观看| 日韩成人久久| 欧美激情综合亚洲一二区| 九九热播视频在线精品6| 国产91精品网站| 日韩88av| 精品国产免费人成电影在线观... 精品国产免费久久久久久尖叫 | 欧美在线免费观看视频| 在线观看免费国产小视频| 亚洲大片在线观看| 四虎成人免费在线| 欧美三级韩国三级日本一级| 免费在线观看黄| 亚洲第一av在线| 超级碰碰久久| 日本美女视频一区二区| 99九九视频| 久久精品免费| 经典三级在线视频| 91网站黄www| 国产精品黄页网站在线播放免费| 一区二区三区国产豹纹内裤在线 | 国产丝袜精品丝袜| 正在播放欧美一区| 欧美黄色录像| 成人黄色网免费| 久久五月激情| 亚洲美免无码中文字幕在线| 亚洲女同ⅹxx女同tv| 成人一区二区不卡免费| 亚洲国产精品系列| 亚洲图色一区二区三区| 成人有码视频在线播放| 奇米888四色在线精品| 精品99在线视频| 精品高清一区二区三区| h片在线观看| 97国产suv精品一区二区62| 日韩欧美精品综合| 天堂va久久久噜噜噜久久va| 国产欧美一区二区精品性色 | 黑丝美女久久久| 电影在线观看一区| 97久久精品国产| 妖精视频成人观看www| 每日在线观看av| 黄色一区二区三区| 宅男在线观看免费高清网站| 美女视频黄免费的亚洲男人天堂| 成人动漫免费在线观看| 裸体裸乳免费看| 亚洲成人一区二区在线观看| 久草在线资源站手机版| 国产精品96久久久久久| 国内精品视频666| 最新在线观看av网站| 亚洲人成电影在线观看天堂色| 国产成人一区| 日日噜噜夜夜狠狠久久丁香五月| 亚洲品质自拍视频| 一区二区三区短视频| 成人欧美在线视频| 26uuu欧美日本| √天堂8在线网| 日本精品性网站在线观看| 蜜桃一区二区三区在线| 性史性dvd影片农村毛片| 亚洲一区二区久久| 激情视频一区| 1024欧美极品| 伊是香蕉大人久久| 国产视频一区在线观看一区免费| 久久婷五月综合| 亚洲毛片一区二区| 1024精品一区二区三区| 特黄aaaaaaaaa毛片免费视频| 国产亚洲视频在线观看| 亚洲视频大全| 四虎电影院在线观看| 97在线观看视频| 福利一区二区在线观看| yellow91字幕网在线| 国产精品精品一区二区三区午夜版 | 国产一区二区0| 日本福利在线观看| 欧美精品久久久久久久| 国产呦萝稀缺另类资源| av资源在线观看免费高清| …久久精品99久久香蕉国产| 国产传媒久久文化传媒| 国产美女福利在线| 99影视tv| 狠狠干狠狠久久| 热久久天天拍国产| 午夜免费啪视频观看视频| 97在线精品视频| 久久久久99精品国产片| 日韩综合久久| 精品少妇人欧美激情在线观看| 精品日韩一区二区三区| 性感少妇一区| 黄色成人在线观看| 久久av一区二区三区亚洲| 欧美日韩一区精品| 韩国精品一区二区三区| 免费在线视频你懂得| 95av在线视频| 亚洲国产视频在线| 色综合五月天| 性网站在线免费观看| 欧美在线免费看| 综合久久久久综合| 日韩有码一区| 日本欧美亚洲| 91精品国产自产在线| 精品国产1区2区| 欧美日本一区| 秋霞a级毛片在线看| 欧美久久电影| 精品国产凹凸成av人导航| 另类综合日韩欧美亚洲| 欧美激情20| 99精品人妻少妇一区二区| 麻豆成人在线看| 久久精品亚洲精品国产欧美kt∨| 亚洲国产视频二区| 成人午夜影院| 成人h视频在线观看播放| 欧美性高潮床叫视频| 日韩一级大片| 欧美一区国产| 久久国产精品国产精品| 国产精品白丝jk喷水视频一区| 婷婷综合在线观看| 中文日韩欧美| 极品视频在线| 黄色影院一级片| 国产精品第一区| 欧美精品123区| 国产91精品在线观看| 狼人精品一区二区三区在线| 一级片免费看| 激情一区二区三区| 亚洲片国产一区一级在线观看| 国产亚洲制服色| 国产一区二区亚洲| 欧美日韩在线资源| 国产夫妻自拍一区| 国产aaa精品| 欧美一级在线观看| 2020日本不卡一区二区视频| 国产在线日韩精品| 日本大片在线播放| 波多野结衣作品集| 亚洲xxxx在线| 在线成人免费网站| 午夜激情久久久| 久久精品999| 亚洲精品aaaaa| 国产91在线视频蝌蚪| 免费观看精品视频| 国产aⅴ精品一区二区三区黄| 日韩精品在线播放| 亚洲免费三区一区二区| 久久精品国语| 久久99国产精品久久99大师| 1pondo在线播放免费| www黄色av| 国产日韩精品推荐| 欧美成人精品三级在线观看| 在线欧美一区二区| 97精品久久久久中文字幕| 俺要去色综合狠狠| 丁香婷婷久久| 触手亚洲一区二区三区| 欧美一级黄色影院| 日本一区不卡| 国产精品视频久久久久| 中文字幕久热精品视频在线| 在线观看亚洲一区| 国产精品欧美极品| 久久成人综合网| 国产精品地址| 欧美aaaaaaaa牛牛影院| 亚洲天堂一区二区| 日本不卡在线|